1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +00:00

Takes a stab at what might happen if you read from Nick.

This commit is contained in:
Thomas Harte 2021-07-03 13:06:07 -04:00
parent c5944efe50
commit 2a6fff2008
3 changed files with 33 additions and 6 deletions

View File

@ -358,6 +358,13 @@ template <bool has_disk_controller> class ConcreteMachine:
}
break;
case 0x80: case 0x81: case 0x82: case 0x83:
case 0x84: case 0x85: case 0x86: case 0x87:
case 0x88: case 0x89: case 0x8a: case 0x8b:
case 0x8c: case 0x8d: case 0x8e: case 0x8f:
*cycle.value = nick_->read();
break;
case 0xb0: *cycle.value = pages_[0]; break;
case 0xb1: *cycle.value = pages_[1]; break;
case 0xb2: *cycle.value = pages_[2]; break;

View File

@ -91,8 +91,8 @@ void Nick::write(uint16_t address, uint8_t value) {
}
}
uint8_t Nick::read([[maybe_unused]] uint16_t address) {
return 0xff;
uint8_t Nick::read() {
return last_read_;
}
Cycles Nick::get_time_until_z80_slot(Cycles after_period) const {
@ -141,9 +141,6 @@ void Nick::run_for(Cycles duration) {
// HSYNC is signalled for four windows at the start of the line.
// I currently believe this happens regardless of Vsync mode.
//
// This is also when the non-palette line parameters
// are loaded, if appropriate.
if(!window) {
set_output_type(OutputType::Sync);
@ -153,6 +150,9 @@ void Nick::run_for(Cycles duration) {
if(!right_margin_) is_sync_or_pixels_ = false;
}
// Default to noting read.
last_read_ = 0xff;
while(window < 4 && window < end_window) {
if(should_reload_line_parameters_) {
switch(window) {
@ -161,6 +161,9 @@ void Nick::run_for(Cycles duration) {
// Byte 0: lines remaining.
lines_remaining_ = ram_[line_parameter_pointer_];
// Byte 1: current interrupt output plus graphics modes...
last_read_ = ram_[line_parameter_pointer_ + 1];
// Set the new interrupt line output.
interrupt_line_ = ram_[line_parameter_pointer_ + 1] & 0x80;
@ -200,6 +203,7 @@ void Nick::run_for(Cycles duration) {
// Determine the margins.
left_margin_ = ram_[line_parameter_pointer_ + 2] & 0x3f;
right_margin_ = ram_[line_parameter_pointer_ + 3] & 0x3f;
last_read_ = ram_[line_parameter_pointer_ + 3];
// Set up the alternative palettes,
switch(mode_) {
@ -249,6 +253,7 @@ void Nick::run_for(Cycles duration) {
start_line_data_pointer_[0] |= ram_[line_parameter_pointer_ + 5] << 8;
line_data_pointer_[0] = start_line_data_pointer_[0];
last_read_ = ram_[line_parameter_pointer_ + 5];
break;
// Fourth slot: Line data pointer 2.
@ -257,6 +262,7 @@ void Nick::run_for(Cycles duration) {
start_line_data_pointer_[1] |= ram_[line_parameter_pointer_ + 7] << 8;
line_data_pointer_[1] = start_line_data_pointer_[1];
last_read_ = ram_[line_parameter_pointer_ + 7];
break;
}
}
@ -301,6 +307,7 @@ void Nick::run_for(Cycles duration) {
assert(base < 7);
palette_[base] = mapped_colour(ram_[line_parameter_pointer_ + base + 8]);
palette_[base + 1] = mapped_colour(ram_[line_parameter_pointer_ + base + 9]);
last_read_ = ram_[line_parameter_pointer_ + base + 9];
}
++output_duration_;
@ -534,6 +541,7 @@ template <int bpp, bool is_lpixel> void Nick::output_pixel(uint16_t *target, int
ram_[(line_data_pointer_[0] + index + 1) & 0xffff]
};
index += is_lpixel ? 1 : 2;
last_read_ = pixels[1];
switch(bpp) {
default:
@ -582,6 +590,7 @@ template <int bpp, int index_bits> void Nick::output_character(uint16_t *target,
(line_data_pointer_[1] << index_bits) +
(character & ((1 << index_bits) - 1))
) & 0xffff];
last_read_ = pixels;
switch(bpp) {
default:
@ -607,6 +616,7 @@ template <int bpp> void Nick::output_attributed(uint16_t *target, int columns) c
for(int c = 0; c < columns; c++) {
const uint8_t pixels = ram_[(line_data_pointer_[1] + c) & 0xffff];
const uint8_t attributes = ram_[(line_data_pointer_[0] + c) & 0xffff];
last_read_ = pixels;
const uint16_t palette[2] = {
palette_[attributes >> 4], palette_[attributes & 0x0f]

View File

@ -19,8 +19,17 @@ class Nick {
public:
Nick(const uint8_t *ram);
/// Writes to a Nick register; only the low two bits are decoded.
void write(uint16_t address, uint8_t value);
uint8_t read(uint16_t address);
/// Reads from the Nick range. Nobody seems to be completely clear what
/// this should return; I've set it up to return the last fetched video or mode
/// line byte during periods when those things are being fetched, 0xff at all
/// other times. Including during refresh, since I don't know what addresses
/// are generated then.
///
/// This likely isn't accurate, but is the most accurate guess I could make.
uint8_t read();
void run_for(Cycles);
Cycles get_time_until_z80_slot(Cycles after_period) const;
@ -60,6 +69,7 @@ class Nick {
bool should_reload_line_parameters_ = true;
uint16_t line_data_pointer_[2];
uint16_t start_line_data_pointer_[2];
mutable uint8_t last_read_ = 0xff;
// Current mode line parameters.
uint8_t lines_remaining_ = 0x00;