mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Ensured counter-intuitive CRTC writes get through, taking the opportunity to correct my handling of port IO in general: selecting multiple devices for input results in a logical AND (i.e. open collector mode), and both the CRTC and gate array will receive data from 'input's if applicable.
This commit is contained in:
parent
6a6e5ae79c
commit
4961fda2a9
@ -579,48 +579,7 @@ class ConcreteMachine:
|
||||
case CPU::Z80::PartialMachineCycle::Output:
|
||||
// Check for a gate array access.
|
||||
if((address & 0xc000) == 0x4000) {
|
||||
switch(*cycle.value >> 6) {
|
||||
case 0: crtc_bus_handler_.select_pen(*cycle.value & 0x1f); break;
|
||||
case 1: crtc_bus_handler_.set_colour(*cycle.value & 0x1f); break;
|
||||
case 2:
|
||||
// Perform ROM paging.
|
||||
read_pointers_[0] = (*cycle.value & 4) ? write_pointers_[0] : roms_[rom_model_].data();
|
||||
|
||||
upper_rom_is_paged_ = !(*cycle.value & 8);
|
||||
read_pointers_[3] = upper_rom_is_paged_ ? roms_[upper_rom_].data() : write_pointers_[3];
|
||||
|
||||
// Reset the interrupt timer if requested.
|
||||
if(*cycle.value & 0x10) interrupt_timer_.reset_count();
|
||||
|
||||
// Post the next mode.
|
||||
crtc_bus_handler_.set_next_mode(*cycle.value & 3);
|
||||
break;
|
||||
case 3:
|
||||
// Perform RAM paging, if 128kb is permitted.
|
||||
if(has_128k_) {
|
||||
bool adjust_low_read_pointer = read_pointers_[0] == write_pointers_[0];
|
||||
bool adjust_high_read_pointer = read_pointers_[3] == write_pointers_[3];
|
||||
#define RAM_BANK(x) &ram_[x * 16384]
|
||||
#define RAM_CONFIG(a, b, c, d) write_pointers_[0] = RAM_BANK(a); write_pointers_[1] = RAM_BANK(b); write_pointers_[2] = RAM_BANK(c); write_pointers_[3] = RAM_BANK(d);
|
||||
switch(*cycle.value & 7) {
|
||||
case 0: RAM_CONFIG(0, 1, 2, 3); break;
|
||||
case 1: RAM_CONFIG(0, 1, 2, 7); break;
|
||||
case 2: RAM_CONFIG(4, 5, 6, 7); break;
|
||||
case 3: RAM_CONFIG(0, 3, 2, 7); break;
|
||||
case 4: RAM_CONFIG(0, 4, 2, 3); break;
|
||||
case 5: RAM_CONFIG(0, 5, 2, 3); break;
|
||||
case 6: RAM_CONFIG(0, 6, 2, 3); break;
|
||||
case 7: RAM_CONFIG(0, 7, 2, 3); break;
|
||||
}
|
||||
#undef RAM_CONFIG
|
||||
#undef RAM_BANK
|
||||
if(adjust_low_read_pointer) read_pointers_[0] = write_pointers_[0];
|
||||
read_pointers_[1] = write_pointers_[1];
|
||||
read_pointers_[2] = write_pointers_[2];
|
||||
if(adjust_high_read_pointer) read_pointers_[3] = write_pointers_[3];
|
||||
}
|
||||
break;
|
||||
}
|
||||
write_to_gate_array(*cycle.value);
|
||||
}
|
||||
|
||||
// Check for an upper ROM selection
|
||||
@ -634,7 +593,7 @@ class ConcreteMachine:
|
||||
switch((address >> 8) & 3) {
|
||||
case 0: crtc_.select_register(*cycle.value); break;
|
||||
case 1: crtc_.set_register(*cycle.value); break;
|
||||
case 2: case 3: printf("Illegal CRTC write?\n"); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -657,23 +616,31 @@ class ConcreteMachine:
|
||||
// Default to nothing answering
|
||||
*cycle.value = 0xff;
|
||||
|
||||
// Check for a CRTC access
|
||||
if(!(address & 0x4000)) {
|
||||
switch((address >> 8) & 3) {
|
||||
case 0: case 1: printf("Illegal CRTC read?\n"); break;
|
||||
case 2: *cycle.value = crtc_.get_status(); break;
|
||||
case 3: *cycle.value = crtc_.get_register(); break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for a PIO access
|
||||
if(!(address & 0x800)) {
|
||||
*cycle.value = i8255_.get_register((address >> 8) & 3);
|
||||
*cycle.value &= i8255_.get_register((address >> 8) & 3);
|
||||
}
|
||||
|
||||
// Check for an FDC access
|
||||
if(has_fdc_ && (address & 0x580) == 0x100) {
|
||||
*cycle.value = fdc_.get_register(address & 1);
|
||||
*cycle.value &= fdc_.get_register(address & 1);
|
||||
}
|
||||
|
||||
// Check for a CRTC access; the below is not a typo — the CRTC can be selected
|
||||
// for writing via an input, and will sample whatever happens to be available
|
||||
if(!(address & 0x4000)) {
|
||||
switch((address >> 8) & 3) {
|
||||
case 0: crtc_.select_register(*cycle.value); break;
|
||||
case 1: crtc_.set_register(*cycle.value); break;
|
||||
case 2: *cycle.value &= crtc_.get_status(); break;
|
||||
case 3: *cycle.value &= crtc_.get_register(); break;
|
||||
}
|
||||
}
|
||||
|
||||
// As with the CRTC, the gate array will sample the bus if the address decoding
|
||||
// implies that it should, unaware of data direction
|
||||
if((address & 0xc000) == 0x4000) {
|
||||
write_to_gate_array(*cycle.value);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -794,6 +761,51 @@ class ConcreteMachine:
|
||||
}
|
||||
|
||||
private:
|
||||
inline void write_to_gate_array(uint8_t value) {
|
||||
switch(value >> 6) {
|
||||
case 0: crtc_bus_handler_.select_pen(value & 0x1f); break;
|
||||
case 1: crtc_bus_handler_.set_colour(value & 0x1f); break;
|
||||
case 2:
|
||||
// Perform ROM paging.
|
||||
read_pointers_[0] = (value & 4) ? write_pointers_[0] : roms_[rom_model_].data();
|
||||
|
||||
upper_rom_is_paged_ = !(value & 8);
|
||||
read_pointers_[3] = upper_rom_is_paged_ ? roms_[upper_rom_].data() : write_pointers_[3];
|
||||
|
||||
// Reset the interrupt timer if requested.
|
||||
if(value & 0x10) interrupt_timer_.reset_count();
|
||||
|
||||
// Post the next mode.
|
||||
crtc_bus_handler_.set_next_mode(value & 3);
|
||||
break;
|
||||
case 3:
|
||||
// Perform RAM paging, if 128kb is permitted.
|
||||
if(has_128k_) {
|
||||
bool adjust_low_read_pointer = read_pointers_[0] == write_pointers_[0];
|
||||
bool adjust_high_read_pointer = read_pointers_[3] == write_pointers_[3];
|
||||
#define RAM_BANK(x) &ram_[x * 16384]
|
||||
#define RAM_CONFIG(a, b, c, d) write_pointers_[0] = RAM_BANK(a); write_pointers_[1] = RAM_BANK(b); write_pointers_[2] = RAM_BANK(c); write_pointers_[3] = RAM_BANK(d);
|
||||
switch(value & 7) {
|
||||
case 0: RAM_CONFIG(0, 1, 2, 3); break;
|
||||
case 1: RAM_CONFIG(0, 1, 2, 7); break;
|
||||
case 2: RAM_CONFIG(4, 5, 6, 7); break;
|
||||
case 3: RAM_CONFIG(0, 3, 2, 7); break;
|
||||
case 4: RAM_CONFIG(0, 4, 2, 3); break;
|
||||
case 5: RAM_CONFIG(0, 5, 2, 3); break;
|
||||
case 6: RAM_CONFIG(0, 6, 2, 3); break;
|
||||
case 7: RAM_CONFIG(0, 7, 2, 3); break;
|
||||
}
|
||||
#undef RAM_CONFIG
|
||||
#undef RAM_BANK
|
||||
if(adjust_low_read_pointer) read_pointers_[0] = write_pointers_[0];
|
||||
read_pointers_[1] = write_pointers_[1];
|
||||
read_pointers_[2] = write_pointers_[2];
|
||||
if(adjust_high_read_pointer) read_pointers_[3] = write_pointers_[3];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CPU::Z80::Processor<ConcreteMachine> z80_;
|
||||
|
||||
CRTCBusHandler crtc_bus_handler_;
|
||||
|
Loading…
Reference in New Issue
Block a user