mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-27 16:31:31 +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:
commit
0f85cffc78
@ -30,13 +30,7 @@ class ConcreteMachine:
|
||||
public Tape::Delegate,
|
||||
public Utility::TypeRecipient {
|
||||
public:
|
||||
ConcreteMachine() :
|
||||
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) {
|
||||
ConcreteMachine() : m6502_(*this) {
|
||||
memset(key_states_, 0, sizeof(key_states_));
|
||||
for(int c = 0; c < 16; c++)
|
||||
memset(roms_[c], 0xff, 16384);
|
||||
@ -435,39 +429,41 @@ class ConcreteMachine:
|
||||
|
||||
// Things that directly constitute the memory map.
|
||||
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];
|
||||
std::vector<uint8_t> dfs_, adfs_;
|
||||
|
||||
// Paging
|
||||
ROMSlot active_rom_;
|
||||
bool keyboard_is_active_, basic_is_active_;
|
||||
ROMSlot active_rom_ = ROMSlot::ROMSlot0;
|
||||
bool keyboard_is_active_ = false;
|
||||
bool basic_is_active_ = false;
|
||||
|
||||
// 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];
|
||||
|
||||
// Counters related to simultaneous subsystems
|
||||
Cycles cycles_since_display_update_;
|
||||
Cycles cycles_since_audio_update_;
|
||||
int cycles_until_display_interrupt_;
|
||||
Interrupt next_display_interrupt_;
|
||||
VideoOutput::Range video_access_range_;
|
||||
Cycles cycles_since_display_update_ = 0;
|
||||
Cycles cycles_since_audio_update_ = 0;
|
||||
int cycles_until_display_interrupt_ = 0;
|
||||
Interrupt next_display_interrupt_ = Interrupt::RealTimeClock;
|
||||
VideoOutput::Range video_access_range_ = {0, 0xffff};
|
||||
|
||||
// Tape
|
||||
Tape tape_;
|
||||
bool use_fast_tape_hack_;
|
||||
bool fast_load_is_in_data_;
|
||||
bool use_fast_tape_hack_ = false;
|
||||
bool fast_load_is_in_data_ = false;
|
||||
|
||||
// Disk
|
||||
std::unique_ptr<Plus3> plus3_;
|
||||
bool is_holding_shift_;
|
||||
int shift_restart_counter_;
|
||||
bool is_holding_shift_ = false;
|
||||
int shift_restart_counter_ = 0;
|
||||
|
||||
// Outputs
|
||||
std::unique_ptr<VideoOutput> video_output_;
|
||||
std::shared_ptr<Speaker> speaker_;
|
||||
bool speaker_is_enabled_;
|
||||
bool speaker_is_enabled_ = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
using namespace Electron;
|
||||
|
||||
Plus3::Plus3() : WD1770(P1770), last_control_(0) {
|
||||
Plus3::Plus3() : WD1770(P1770) {
|
||||
set_control_register(last_control_, 0xff);
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,8 @@ class Plus3 : public WD::WD1770 {
|
||||
private:
|
||||
void set_control_register(uint8_t control, uint8_t changes);
|
||||
std::shared_ptr<Storage::Disk::Drive> drives_[2];
|
||||
int selected_drive_;
|
||||
uint8_t last_control_;
|
||||
int selected_drive_ = 0;
|
||||
uint8_t last_control_ = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -25,9 +25,9 @@ class Speaker: public ::Outputs::Filter<Speaker> {
|
||||
static const unsigned int clock_rate_divider = 8;
|
||||
|
||||
private:
|
||||
unsigned int counter_;
|
||||
unsigned int divider_;
|
||||
bool is_enabled_;
|
||||
unsigned int counter_ = 0;
|
||||
unsigned int divider_ = 0;
|
||||
bool is_enabled_ = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -10,14 +10,7 @@
|
||||
|
||||
using namespace Electron;
|
||||
|
||||
Tape::Tape() :
|
||||
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) {
|
||||
Tape::Tape() : TapePlayer(2000000) {
|
||||
shifter_.set_delegate(this);
|
||||
}
|
||||
|
||||
|
@ -53,21 +53,22 @@ class Tape:
|
||||
|
||||
struct {
|
||||
int minimum_bits_until_full;
|
||||
} input_;
|
||||
} input_ = {0};
|
||||
struct {
|
||||
unsigned int cycles_into_pulse;
|
||||
unsigned int bits_remaining_until_empty;
|
||||
} output_;
|
||||
} output_ = {.bits_remaining_until_empty = 0, .cycles_into_pulse = 0};
|
||||
|
||||
bool is_running_;
|
||||
bool is_enabled_;
|
||||
bool is_in_input_mode_;
|
||||
bool is_running_ = false;
|
||||
bool is_enabled_ = false;
|
||||
bool is_in_input_mode_ = false;
|
||||
|
||||
inline void evaluate_interrupts();
|
||||
uint16_t data_register_;
|
||||
uint16_t data_register_ = 0;
|
||||
|
||||
uint8_t interrupt_status_, last_posted_interrupt_status_;
|
||||
Delegate *delegate_;
|
||||
uint8_t interrupt_status_ = 0;
|
||||
uint8_t last_posted_interrupt_status_ = 0;
|
||||
Delegate *delegate_ = nullptr;
|
||||
|
||||
::Storage::Tape::Acorn::Shifter shifter_;
|
||||
};
|
||||
|
@ -36,13 +36,7 @@ namespace {
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
VideoOutput::VideoOutput(uint8_t *memory) :
|
||||
ram_(memory),
|
||||
current_pixel_line_(-1),
|
||||
output_position_(0),
|
||||
screen_mode_(6),
|
||||
screen_map_pointer_(0),
|
||||
cycles_into_draw_action_(0) {
|
||||
VideoOutput::VideoOutput(uint8_t *memory) : ram_(memory) {
|
||||
memset(palette_, 0xf, sizeof(palette_));
|
||||
setup_screen_map();
|
||||
setup_base_address();
|
||||
|
@ -80,12 +80,13 @@ class VideoOutput {
|
||||
inline void output_pixels(unsigned int number_of_cycles);
|
||||
inline void setup_base_address();
|
||||
|
||||
int output_position_, unused_cycles_;
|
||||
int output_position_ = 0;
|
||||
int unused_cycles_ = 0;
|
||||
|
||||
uint8_t palette_[16];
|
||||
uint8_t screen_mode_;
|
||||
uint16_t screen_mode_base_address_;
|
||||
uint16_t start_screen_address_;
|
||||
uint8_t screen_mode_ = 6;
|
||||
uint16_t screen_mode_base_address_ = 0;
|
||||
uint16_t start_screen_address_ = 0;
|
||||
|
||||
uint8_t *ram_;
|
||||
struct {
|
||||
@ -97,14 +98,18 @@ class VideoOutput {
|
||||
} palette_tables_;
|
||||
|
||||
// Display generation.
|
||||
uint16_t start_line_address_, current_screen_address_;
|
||||
int current_pixel_line_, current_pixel_column_, current_character_row_;
|
||||
uint8_t last_pixel_byte_;
|
||||
bool is_blank_line_;
|
||||
uint16_t start_line_address_ = 0;
|
||||
uint16_t current_screen_address_ = 0;
|
||||
int current_pixel_line_ = -1;
|
||||
int current_pixel_column_ = 0;
|
||||
int current_character_row_ = 0;
|
||||
uint8_t last_pixel_byte_ = 0;
|
||||
bool is_blank_line_ = false;
|
||||
|
||||
// CRT output
|
||||
uint8_t *current_output_target_, *initial_output_target_;
|
||||
unsigned int current_output_divider_;
|
||||
uint8_t *current_output_target_ = nullptr;
|
||||
uint8_t *initial_output_target_ = nullptr;
|
||||
unsigned int current_output_divider_ = 1;
|
||||
|
||||
std::shared_ptr<Outputs::CRT::CRT> crt_;
|
||||
|
||||
@ -119,8 +124,8 @@ class VideoOutput {
|
||||
void setup_screen_map();
|
||||
void emplace_blank_line();
|
||||
void emplace_pixel_line();
|
||||
size_t screen_map_pointer_;
|
||||
int cycles_into_draw_action_;
|
||||
size_t screen_map_pointer_ = 0;
|
||||
int cycles_into_draw_action_ = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user