mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-15 05:31:30 +00:00
Ensures ADB microcontroller is clocked.
And runs at the 'correct' speed (i.e. modulo my instruction-by-instruction implementation).
This commit is contained in:
parent
7f62732476
commit
57e0fdfadc
@ -35,13 +35,12 @@ void Executor::set_rom(const std::vector<uint8_t> &rom) {
|
||||
const auto length = std::min(size_t(0x1000), rom.size());
|
||||
memcpy(&memory_[0x2000 - length], rom.data(), length);
|
||||
reset();
|
||||
|
||||
// TEMPORARY: just to test initial wiring.
|
||||
run_for(Cycles(13000));
|
||||
}
|
||||
|
||||
void Executor::run_for(Cycles cycles) {
|
||||
CachingExecutor::run_for(cycles.as<int>());
|
||||
// The incoming clock is divided by four.
|
||||
cycles_ += cycles;
|
||||
CachingExecutor::run_for(cycles_.divide(Cycles(4)).as<int>());
|
||||
}
|
||||
|
||||
void Executor::reset() {
|
||||
@ -128,7 +127,7 @@ template<bool is_brk> inline void Executor::perform_interrupt() {
|
||||
}
|
||||
|
||||
template <Operation operation, AddressingMode addressing_mode> void Executor::perform() {
|
||||
printf("%04x\t%02x\t%d %d\t[x:%02x s:%02x]\t(%s)\n", program_counter_ & 0x1fff, memory_[program_counter_ & 0x1fff], int(operation), int(addressing_mode), x_, s_, __PRETTY_FUNCTION__ );
|
||||
// printf("%04x\t%02x\t%d %d\t[x:%02x s:%02x]\t(%s)\n", program_counter_ & 0x1fff, memory_[program_counter_ & 0x1fff], int(operation), int(addressing_mode), x_, s_, __PRETTY_FUNCTION__ );
|
||||
|
||||
// Post cycle cost; this emulation _does not provide accurate timing_.
|
||||
#define TLength(mode, base) case AddressingMode::mode: subtract_duration(base + t_lengths[index_mode_]); break;
|
||||
|
@ -136,6 +136,8 @@ class Executor: public CachingExecutor {
|
||||
inline void set_flags(uint8_t);
|
||||
inline uint8_t flags();
|
||||
template<bool is_brk> inline void perform_interrupt();
|
||||
|
||||
Cycles cycles_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -215,3 +215,7 @@ uint8_t GLU::read_microcontroller_address(uint16_t address) {
|
||||
void GLU::set_microcontroller_rom(const std::vector<uint8_t> &rom) {
|
||||
executor_.set_rom(rom);
|
||||
}
|
||||
|
||||
void GLU::run_for(Cycles cycles) {
|
||||
executor_.run_for(cycles);
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ class GLU {
|
||||
|
||||
void set_microcontroller_rom(const std::vector<uint8_t> &rom);
|
||||
|
||||
void run_for(Cycles cycles);
|
||||
|
||||
private:
|
||||
bool is_rom03_ = false;
|
||||
std::vector<uint8_t> next_command_;
|
||||
|
@ -96,7 +96,7 @@ class ConcreteMachine:
|
||||
}
|
||||
rom_ = *roms[0];
|
||||
video_->set_character_rom(*roms[1]);
|
||||
adb_glu_.set_microcontroller_rom(*roms[2]);
|
||||
adb_glu_->set_microcontroller_rom(*roms[2]);
|
||||
|
||||
// Run only the currently-interesting self test.
|
||||
rom_[0x36402] = 2;
|
||||
@ -160,7 +160,7 @@ class ConcreteMachine:
|
||||
video_->set_internal_ram(&ram_[ram_.size() - 128*1024]);
|
||||
|
||||
// Select appropriate ADB behaviour.
|
||||
adb_glu_.set_is_rom03(target.model == Target::Model::ROM03);
|
||||
adb_glu_->set_is_rom03(target.model == Target::Model::ROM03);
|
||||
|
||||
// Attach drives to the IWM.
|
||||
iwm_->set_drive(0, &drives35_[0]);
|
||||
@ -425,32 +425,32 @@ class ConcreteMachine:
|
||||
|
||||
// ADB and keyboard.
|
||||
case Read(0xc000):
|
||||
*value = adb_glu_.get_keyboard_data();
|
||||
*value = adb_glu_->get_keyboard_data();
|
||||
break;
|
||||
case Read(0xc010):
|
||||
*value = adb_glu_.get_any_key_down() ? 0x80 : 0x00;
|
||||
*value = adb_glu_->get_any_key_down() ? 0x80 : 0x00;
|
||||
[[fallthrough]];
|
||||
case Write(0xc010):
|
||||
adb_glu_.clear_key_strobe();
|
||||
adb_glu_->clear_key_strobe();
|
||||
break;
|
||||
|
||||
case Read(0xc024):
|
||||
*value = adb_glu_.get_mouse_data();
|
||||
*value = adb_glu_->get_mouse_data();
|
||||
break;
|
||||
case Read(0xc025):
|
||||
*value = adb_glu_.get_modifier_status();
|
||||
*value = adb_glu_->get_modifier_status();
|
||||
break;
|
||||
case Read(0xc026):
|
||||
*value = adb_glu_.get_data();
|
||||
*value = adb_glu_->get_data();
|
||||
break;
|
||||
case Write(0xc026):
|
||||
adb_glu_.set_command(*value);
|
||||
adb_glu_->set_command(*value);
|
||||
break;
|
||||
case Read(0xc027):
|
||||
*value = adb_glu_.get_status();
|
||||
*value = adb_glu_->get_status();
|
||||
break;
|
||||
case Write(0xc027):
|
||||
adb_glu_.set_status(*value);
|
||||
adb_glu_->set_status(*value);
|
||||
break;
|
||||
|
||||
// The SCC.
|
||||
@ -875,6 +875,7 @@ class ConcreteMachine:
|
||||
video_ += duration;
|
||||
iwm_ += duration;
|
||||
cycles_since_audio_update_ += duration;
|
||||
adb_glu_ += duration;
|
||||
total += decltype(total)(duration.as_integral());
|
||||
|
||||
if(cycles_since_audio_update_ >= cycles_until_audio_event_) {
|
||||
@ -915,7 +916,7 @@ class ConcreteMachine:
|
||||
|
||||
Apple::Clock::ParallelClock clock_;
|
||||
JustInTimeActor<Apple::IIgs::Video::Video, 1, 2, Cycles> video_; // i.e. run video at 7Mhz.
|
||||
Apple::IIgs::ADB::GLU adb_glu_;
|
||||
JustInTimeActor<Apple::IIgs::ADB::GLU, 1, 4, Cycles> adb_glu_;
|
||||
Zilog::SCC::z8530 scc_;
|
||||
JustInTimeActor<Apple::IWM, 1, 2, Cycles> iwm_;
|
||||
Cycles cycles_since_clock_tick_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user