1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-13 06:23:59 +00:00

Merge pull request #232 from TomHarte/ElectronShift

Ensures all parts of the Electron have a fully-defined initial state.
This commit is contained in:
Thomas Harte 2017-08-31 22:29:50 -04:00 committed by GitHub
commit 0f85cffc78
8 changed files with 51 additions and 62 deletions

View File

@ -30,13 +30,7 @@ class ConcreteMachine:
public Tape::Delegate, public Tape::Delegate,
public Utility::TypeRecipient { public Utility::TypeRecipient {
public: public:
ConcreteMachine() : ConcreteMachine() : m6502_(*this) {
m6502_(*this),
interrupt_control_(0),
interrupt_status_(Interrupt::PowerOnReset | Interrupt::TransmitDataEmpty | 0x80),
cycles_since_audio_update_(0),
use_fast_tape_hack_(false),
cycles_until_display_interrupt_(0) {
memset(key_states_, 0, sizeof(key_states_)); memset(key_states_, 0, sizeof(key_states_));
for(int c = 0; c < 16; c++) for(int c = 0; c < 16; c++)
memset(roms_[c], 0xff, 16384); memset(roms_[c], 0xff, 16384);
@ -435,39 +429,41 @@ class ConcreteMachine:
// Things that directly constitute the memory map. // Things that directly constitute the memory map.
uint8_t roms_[16][16384]; uint8_t roms_[16][16384];
bool rom_write_masks_[16]; bool rom_write_masks_[16] = {false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false};
uint8_t os_[16384], ram_[32768]; uint8_t os_[16384], ram_[32768];
std::vector<uint8_t> dfs_, adfs_; std::vector<uint8_t> dfs_, adfs_;
// Paging // Paging
ROMSlot active_rom_; ROMSlot active_rom_ = ROMSlot::ROMSlot0;
bool keyboard_is_active_, basic_is_active_; bool keyboard_is_active_ = false;
bool basic_is_active_ = false;
// Interrupt and keyboard state // Interrupt and keyboard state
uint8_t interrupt_status_, interrupt_control_; uint8_t interrupt_status_ = Interrupt::PowerOnReset | Interrupt::TransmitDataEmpty | 0x80;
uint8_t interrupt_control_ = 0;
uint8_t key_states_[14]; uint8_t key_states_[14];
// Counters related to simultaneous subsystems // Counters related to simultaneous subsystems
Cycles cycles_since_display_update_; Cycles cycles_since_display_update_ = 0;
Cycles cycles_since_audio_update_; Cycles cycles_since_audio_update_ = 0;
int cycles_until_display_interrupt_; int cycles_until_display_interrupt_ = 0;
Interrupt next_display_interrupt_; Interrupt next_display_interrupt_ = Interrupt::RealTimeClock;
VideoOutput::Range video_access_range_; VideoOutput::Range video_access_range_ = {0, 0xffff};
// Tape // Tape
Tape tape_; Tape tape_;
bool use_fast_tape_hack_; bool use_fast_tape_hack_ = false;
bool fast_load_is_in_data_; bool fast_load_is_in_data_ = false;
// Disk // Disk
std::unique_ptr<Plus3> plus3_; std::unique_ptr<Plus3> plus3_;
bool is_holding_shift_; bool is_holding_shift_ = false;
int shift_restart_counter_; int shift_restart_counter_ = 0;
// Outputs // Outputs
std::unique_ptr<VideoOutput> video_output_; std::unique_ptr<VideoOutput> video_output_;
std::shared_ptr<Speaker> speaker_; std::shared_ptr<Speaker> speaker_;
bool speaker_is_enabled_; bool speaker_is_enabled_ = false;
}; };
} }

View File

@ -10,7 +10,7 @@
using namespace Electron; using namespace Electron;
Plus3::Plus3() : WD1770(P1770), last_control_(0) { Plus3::Plus3() : WD1770(P1770) {
set_control_register(last_control_, 0xff); set_control_register(last_control_, 0xff);
} }

View File

@ -23,8 +23,8 @@ class Plus3 : public WD::WD1770 {
private: private:
void set_control_register(uint8_t control, uint8_t changes); void set_control_register(uint8_t control, uint8_t changes);
std::shared_ptr<Storage::Disk::Drive> drives_[2]; std::shared_ptr<Storage::Disk::Drive> drives_[2];
int selected_drive_; int selected_drive_ = 0;
uint8_t last_control_; uint8_t last_control_ = 0;
}; };
} }

View File

@ -25,9 +25,9 @@ class Speaker: public ::Outputs::Filter<Speaker> {
static const unsigned int clock_rate_divider = 8; static const unsigned int clock_rate_divider = 8;
private: private:
unsigned int counter_; unsigned int counter_ = 0;
unsigned int divider_; unsigned int divider_ = 0;
bool is_enabled_; bool is_enabled_ = false;
}; };
} }

View File

@ -10,14 +10,7 @@
using namespace Electron; using namespace Electron;
Tape::Tape() : Tape::Tape() : TapePlayer(2000000) {
TapePlayer(2000000),
is_running_(false),
data_register_(0),
delegate_(nullptr),
output_({.bits_remaining_until_empty = 0, .cycles_into_pulse = 0}),
last_posted_interrupt_status_(0),
interrupt_status_(0) {
shifter_.set_delegate(this); shifter_.set_delegate(this);
} }

View File

@ -53,21 +53,22 @@ class Tape:
struct { struct {
int minimum_bits_until_full; int minimum_bits_until_full;
} input_; } input_ = {0};
struct { struct {
unsigned int cycles_into_pulse; unsigned int cycles_into_pulse;
unsigned int bits_remaining_until_empty; unsigned int bits_remaining_until_empty;
} output_; } output_ = {.bits_remaining_until_empty = 0, .cycles_into_pulse = 0};
bool is_running_; bool is_running_ = false;
bool is_enabled_; bool is_enabled_ = false;
bool is_in_input_mode_; bool is_in_input_mode_ = false;
inline void evaluate_interrupts(); inline void evaluate_interrupts();
uint16_t data_register_; uint16_t data_register_ = 0;
uint8_t interrupt_status_, last_posted_interrupt_status_; uint8_t interrupt_status_ = 0;
Delegate *delegate_; uint8_t last_posted_interrupt_status_ = 0;
Delegate *delegate_ = nullptr;
::Storage::Tape::Acorn::Shifter shifter_; ::Storage::Tape::Acorn::Shifter shifter_;
}; };

View File

@ -36,13 +36,7 @@ namespace {
#pragma mark - Lifecycle #pragma mark - Lifecycle
VideoOutput::VideoOutput(uint8_t *memory) : VideoOutput::VideoOutput(uint8_t *memory) : ram_(memory) {
ram_(memory),
current_pixel_line_(-1),
output_position_(0),
screen_mode_(6),
screen_map_pointer_(0),
cycles_into_draw_action_(0) {
memset(palette_, 0xf, sizeof(palette_)); memset(palette_, 0xf, sizeof(palette_));
setup_screen_map(); setup_screen_map();
setup_base_address(); setup_base_address();

View File

@ -80,12 +80,13 @@ class VideoOutput {
inline void output_pixels(unsigned int number_of_cycles); inline void output_pixels(unsigned int number_of_cycles);
inline void setup_base_address(); inline void setup_base_address();
int output_position_, unused_cycles_; int output_position_ = 0;
int unused_cycles_ = 0;
uint8_t palette_[16]; uint8_t palette_[16];
uint8_t screen_mode_; uint8_t screen_mode_ = 6;
uint16_t screen_mode_base_address_; uint16_t screen_mode_base_address_ = 0;
uint16_t start_screen_address_; uint16_t start_screen_address_ = 0;
uint8_t *ram_; uint8_t *ram_;
struct { struct {
@ -97,14 +98,18 @@ class VideoOutput {
} palette_tables_; } palette_tables_;
// Display generation. // Display generation.
uint16_t start_line_address_, current_screen_address_; uint16_t start_line_address_ = 0;
int current_pixel_line_, current_pixel_column_, current_character_row_; uint16_t current_screen_address_ = 0;
uint8_t last_pixel_byte_; int current_pixel_line_ = -1;
bool is_blank_line_; int current_pixel_column_ = 0;
int current_character_row_ = 0;
uint8_t last_pixel_byte_ = 0;
bool is_blank_line_ = false;
// CRT output // CRT output
uint8_t *current_output_target_, *initial_output_target_; uint8_t *current_output_target_ = nullptr;
unsigned int current_output_divider_; uint8_t *initial_output_target_ = nullptr;
unsigned int current_output_divider_ = 1;
std::shared_ptr<Outputs::CRT::CRT> crt_; std::shared_ptr<Outputs::CRT::CRT> crt_;
@ -119,8 +124,8 @@ class VideoOutput {
void setup_screen_map(); void setup_screen_map();
void emplace_blank_line(); void emplace_blank_line();
void emplace_pixel_line(); void emplace_pixel_line();
size_t screen_map_pointer_; size_t screen_map_pointer_ = 0;
int cycles_into_draw_action_; int cycles_into_draw_action_ = 0;
}; };
} }