mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-25 16:31:42 +00:00
Sub in basic transliteration of hoglet's FPGA.
This commit is contained in:
parent
aab2dd68b6
commit
59530a12fd
@ -683,7 +683,7 @@ template <bool has_scsi_bus> class ConcreteMachine:
|
|||||||
speaker_.run_for(audio_queue_, cycles_since_audio_update_.divide(Cycles(SoundGenerator::clock_rate_divider)));
|
speaker_.run_for(audio_queue_, cycles_since_audio_update_.divide(Cycles(SoundGenerator::clock_rate_divider)));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void signal_interrupt(Interrupt interrupt) {
|
inline void signal_interrupt(uint8_t interrupt) {
|
||||||
if(!interrupt) {
|
if(!interrupt) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -230,54 +230,97 @@ Outputs::Display::DisplayType VideoOutput::get_display_type() const {
|
|||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
Electron::Interrupt VideoOutput::run_for(const Cycles cycles) {
|
uint8_t VideoOutput::run_for(const Cycles cycles) {
|
||||||
Electron::Interrupt interrupts{};
|
uint8_t interrupts{};
|
||||||
// int number_of_cycles = int(cycles.as_integral());
|
|
||||||
// const auto start_position = output_position_;
|
int number_of_cycles = cycles.as<int>();
|
||||||
// output_position_ = (output_position_ + number_of_cycles) % cycles_per_frame;
|
while(number_of_cycles--) {
|
||||||
//
|
// Horizontal and vertical counter updates.
|
||||||
// const auto test_range = [&](int start, int end) {
|
const bool is_v_end = v_count == v_total();
|
||||||
// if(
|
h_count += 8;
|
||||||
// (start < real_time_clock_interrupt_1 && end >= real_time_clock_interrupt_1) ||
|
if(h_count == h_total) {
|
||||||
// (start < real_time_clock_interrupt_2 && end >= real_time_clock_interrupt_2)
|
h_count = 0;
|
||||||
// ) {
|
++v_count;
|
||||||
// interrupts_ = Electron::Interrupt(interrupts_ | Electron::Interrupt::RealTimeClock);
|
|
||||||
// }
|
if(is_v_end) {
|
||||||
//
|
v_count = 0;
|
||||||
// if(
|
field = !field;
|
||||||
// (start < display_end_interrupt_1 && end >= display_end_interrupt_1) ||
|
}
|
||||||
// (start < display_end_interrupt_2 && end >= display_end_interrupt_2)
|
}
|
||||||
// ) {
|
|
||||||
// interrupts_ = Electron::Interrupt(interrupts_ | Electron::Interrupt::DisplayEnd);
|
// Test for interrupts.
|
||||||
// }
|
if(v_count == v_rtc && ((!field && !h_count) || (field && h_count == h_half))) {
|
||||||
// };
|
interrupts |= static_cast<uint8_t>(Interrupt::RealTimeClock);
|
||||||
//
|
}
|
||||||
// if(output_position_ >= start_position) {
|
if(h_count == hsync_start && ((v_count == v_disp_gph && !mode_text) or (v_count == v_disp_txt && mode_text))) {
|
||||||
// test_range(start_position, output_position_);
|
interrupts |= static_cast<uint8_t>(Interrupt::DisplayEnd);
|
||||||
// } else {
|
}
|
||||||
// test_range(start_position, cycles_per_frame);
|
|
||||||
// test_range(0, output_position_);
|
// Update syncs.
|
||||||
// }
|
if(!field) {
|
||||||
//
|
if(!h_count && v_count == vsync_start) {
|
||||||
// while(number_of_cycles) {
|
vsync_int = true;
|
||||||
// int draw_action_length = screen_map_[screen_map_pointer_].length;
|
} else if(h_count == h_half && v_count == vsync_end) {
|
||||||
// int time_left_in_action = std::min(number_of_cycles, draw_action_length - cycles_into_draw_action_);
|
vsync_int = false;
|
||||||
// if(screen_map_[screen_map_pointer_].type == DrawAction::Pixels) output_pixels(time_left_in_action);
|
}
|
||||||
//
|
} else {
|
||||||
// number_of_cycles -= time_left_in_action;
|
if(h_count == h_half && v_count == vsync_start) {
|
||||||
// cycles_into_draw_action_ += time_left_in_action;
|
vsync_int = true;
|
||||||
// if(cycles_into_draw_action_ == draw_action_length) {
|
} else if(!h_count && v_count == vsync_end + 1) {
|
||||||
// switch(screen_map_[screen_map_pointer_].type) {
|
vsync_int = false;
|
||||||
// case DrawAction::Sync: crt_.output_sync(draw_action_length * crt_cycles_multiplier); break;
|
}
|
||||||
// case DrawAction::ColourBurst: crt_.output_default_colour_burst(draw_action_length * crt_cycles_multiplier); break;
|
}
|
||||||
// case DrawAction::Blank: crt_.output_blank(draw_action_length * crt_cycles_multiplier); break;
|
|
||||||
// case DrawAction::Pixels: end_pixel_line(); break;
|
const auto h_sync_last = hsync_int;
|
||||||
// }
|
if(h_count == hsync_start) {
|
||||||
// screen_map_pointer_ = (screen_map_pointer_ + 1) % screen_map_.size();
|
hsync_int = true;
|
||||||
// cycles_into_draw_action_ = 0;
|
} else if(h_count == hsync_end) {
|
||||||
// if(screen_map_[screen_map_pointer_].type == DrawAction::Pixels) start_pixel_line();
|
hsync_int = false;
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
|
// Update character row on the trailing edge of hsync.
|
||||||
|
if(h_count == hsync_end) {
|
||||||
|
if(is_v_end) {
|
||||||
|
char_row = 0;
|
||||||
|
} else {
|
||||||
|
char_row = last_line() ? 0 : char_row + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable the top bit of the char_row counter outside of text mode.
|
||||||
|
if(!mode_text) {
|
||||||
|
char_row &= 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Latch video address at frame start.
|
||||||
|
if(h_count == h_reset_addr && is_v_end) {
|
||||||
|
row_addr = byte_addr = screen_base;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy byte_addr back into row_addr if a new character row has begun.
|
||||||
|
if(hsync_int) {
|
||||||
|
if(last_line()) {
|
||||||
|
row_addr = byte_addr;
|
||||||
|
} else {
|
||||||
|
byte_addr = row_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment the byte address across the line.
|
||||||
|
// (slghtly pained logic here because the input clock is still at the pixel rate, not the byte rate)
|
||||||
|
if(h_count < h_active) {
|
||||||
|
if(
|
||||||
|
(!mode_40 && !(h_count & 0x7)) ||
|
||||||
|
(mode_40 && ((h_count & 0xf) == 0x8))
|
||||||
|
) {
|
||||||
|
byte_addr += 8;
|
||||||
|
|
||||||
|
if(!(byte_addr & 0b0111'1000'0000'0000)) {
|
||||||
|
byte_addr = mode_base | (byte_addr & 0x0000'0111'1111'1111);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return interrupts;
|
return interrupts;
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ class VideoOutput {
|
|||||||
/// Produces the next @c cycles of video output.
|
/// Produces the next @c cycles of video output.
|
||||||
///
|
///
|
||||||
/// @returns a bit mask of all interrupts triggered.
|
/// @returns a bit mask of all interrupts triggered.
|
||||||
Electron::Interrupt run_for(const Cycles cycles);
|
uint8_t run_for(const Cycles cycles);
|
||||||
|
|
||||||
/// @returns The number of 2Mhz cycles that will pass before completion of an attempted
|
/// @returns The number of 2Mhz cycles that will pass before completion of an attempted
|
||||||
/// IO [/1Mhz] access that is first signalled in the upcoming cycle.
|
/// IO [/1Mhz] access that is first signalled in the upcoming cycle.
|
||||||
|
Loading…
Reference in New Issue
Block a user