mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-08 14:25:05 +00:00
Attempts actual performance of the state machine.
This commit is contained in:
@@ -14,26 +14,28 @@ using namespace Apple;
|
|||||||
|
|
||||||
void DiskII::set_control(Control control, bool on) {
|
void DiskII::set_control(Control control, bool on) {
|
||||||
printf("Set control %d %s\n", control, on ? "on" : "off");
|
printf("Set control %d %s\n", control, on ? "on" : "off");
|
||||||
|
// TODO: seeking, motor control.
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiskII::set_mode(Mode mode) {
|
void DiskII::set_mode(Mode mode) {
|
||||||
printf("Set mode %d\n", mode);
|
printf("Set mode %d\n", mode);
|
||||||
state_ = (state_ & ~0x08) | ((mode == Mode::Write) ? 0x8 : 0x0);
|
inputs_ = (inputs_ & ~0x08) | ((mode == Mode::Write) ? 0x2: 0x0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiskII::select_drive(int drive) {
|
void DiskII::select_drive(int drive) {
|
||||||
printf("Select drive %d\n", drive);
|
printf("Select drive %d\n", drive);
|
||||||
|
// TODO: select a drive.
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiskII::set_data_register(uint8_t value) {
|
void DiskII::set_data_register(uint8_t value) {
|
||||||
printf("Set data register (?)\n");
|
printf("Set data register (?)\n");
|
||||||
state_ |= 0x4;
|
inputs_ |= 0x1;
|
||||||
data_register_ = value;
|
data_register_ = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t DiskII::get_shift_register() {
|
uint8_t DiskII::get_shift_register() {
|
||||||
printf("Get shift register (?)\n");
|
printf("[%02x] ", shift_register_);
|
||||||
state_ &= ~0x4;
|
inputs_ &= ~0x1;
|
||||||
return shift_register_;
|
return shift_register_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,20 +53,42 @@ void DiskII::run_for(const Cycles cycles) {
|
|||||||
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.
|
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.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
// TODO: optimise the resting state.
|
||||||
|
|
||||||
uint8_t command = 0;
|
int integer_cycles = cycles.as_int();
|
||||||
switch(command) {
|
while(integer_cycles--) {
|
||||||
case 0x0: shift_register_ = 0; break; // clear
|
const int address =
|
||||||
case 0x9: shift_register_ = static_cast<uint8_t>(shift_register_ << 1); break; // shift left, bringing in a zero
|
(inputs_ << 2) |
|
||||||
case 0xd: shift_register_ = static_cast<uint8_t>((shift_register_ << 1) | 1); break; // shift left, bringing in a one
|
((shift_register_&0x80) >> 6) |
|
||||||
case 0xa:
|
((state_&0x2) >> 1) |
|
||||||
shift_register_ = (shift_register_ >> 1) | (is_write_protected() ? 0x80 : 0x00);
|
((state_&0x1) << 7) |
|
||||||
break; // shift right, bringing in write protected status
|
((state_&0x4) << 4) |
|
||||||
case 0xb: shift_register_ = data_register_; break; // load
|
((state_&0x8) << 2);
|
||||||
default: break;
|
// TODO: add pulse state in bit 4.
|
||||||
|
|
||||||
|
const uint8_t update = state_machine_[static_cast<std::size_t>(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) {
|
||||||
|
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 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 0xa:
|
||||||
|
shift_register_ = (shift_register_ >> 1) | (is_write_protected() ? 0x80 : 0x00);
|
||||||
|
break; // shift right, bringing in write protected status
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DiskII::is_write_protected() {
|
bool DiskII::is_write_protected() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DiskII::set_state_machine(const std::vector<uint8_t> &state_machine) {
|
||||||
|
state_machine_ = state_machine;
|
||||||
|
// TODO: shuffle ordering here?
|
||||||
|
}
|
||||||
|
@@ -10,7 +10,9 @@
|
|||||||
#define DiskII_hpp
|
#define DiskII_hpp
|
||||||
|
|
||||||
#include "../../ClockReceiver/ClockReceiver.hpp"
|
#include "../../ClockReceiver/ClockReceiver.hpp"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Apple {
|
namespace Apple {
|
||||||
|
|
||||||
@@ -33,13 +35,16 @@ class DiskII {
|
|||||||
uint8_t get_shift_register();
|
uint8_t get_shift_register();
|
||||||
|
|
||||||
void run_for(const Cycles cycles);
|
void run_for(const Cycles cycles);
|
||||||
|
void set_state_machine(const std::vector<uint8_t> &);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t state_ = 0;
|
uint8_t state_ = 0;
|
||||||
|
uint8_t inputs_ = 0;
|
||||||
uint8_t shift_register_ = 0;
|
uint8_t shift_register_ = 0;
|
||||||
uint8_t data_register_ = 0;
|
uint8_t data_register_ = 0;
|
||||||
|
|
||||||
bool is_write_protected();
|
bool is_write_protected();
|
||||||
|
std::vector<uint8_t> state_machine_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,7 @@ DiskIICard::DiskIICard(const ROMMachine::ROMFetcher &rom_fetcher, bool is_16_sec
|
|||||||
"state-machine.rom"
|
"state-machine.rom"
|
||||||
});
|
});
|
||||||
boot_ = std::move(*roms[0]);
|
boot_ = std::move(*roms[0]);
|
||||||
state_machine_ = std::move(*roms[1]);
|
diskii_.set_state_machine(*roms[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiskIICard::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) {
|
void DiskIICard::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint16_t address, uint8_t *value) {
|
||||||
@@ -61,5 +61,5 @@ void DiskIICard::perform_bus_operation(CPU::MOS6502::BusOperation operation, uin
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DiskIICard::run_for(Cycles cycles, int stretches) {
|
void DiskIICard::run_for(Cycles cycles, int stretches) {
|
||||||
diskii_.run_for(cycles);
|
diskii_.run_for(Cycles(cycles.as_int() * 2));
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,6 @@ class DiskIICard: public Card {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint8_t> boot_;
|
std::vector<uint8_t> boot_;
|
||||||
std::vector<uint8_t> state_machine_;
|
|
||||||
Apple::DiskII diskii_;
|
Apple::DiskII diskii_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user