1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-06 01:28:57 +00:00

Introduces extra delays to VRAM access.

This commit is contained in:
Thomas Harte 2018-10-26 20:19:08 -04:00
parent 05a5c7120e
commit bb09762029
2 changed files with 24 additions and 7 deletions

View File

@ -184,6 +184,9 @@ void TMS9918::run_for(const HalfCycles cycles) {
const int end_column = write_pointer_.column + write_cycles; const int end_column = write_pointer_.column + write_cycles;
LineBuffer &line_buffer = line_buffers_[write_pointer_.row]; LineBuffer &line_buffer = line_buffers_[write_pointer_.row];
// Determine what this does to any enqueued VRAM access.
minimum_access_column_ = write_pointer_.column + cycles_until_access_;
cycles_until_access_ -= write_cycles;
// --------------------------------------- // ---------------------------------------
@ -487,6 +490,7 @@ void TMS9918::set_register(int address, uint8_t value) {
// Enqueue the write to occur at the next available slot. // Enqueue the write to occur at the next available slot.
read_ahead_buffer_ = value; read_ahead_buffer_ = value;
queued_access_ = MemoryAccess::Write; queued_access_ = MemoryAccess::Write;
cycles_until_access_ = vram_access_delay();
return; return;
} }
@ -509,11 +513,11 @@ void TMS9918::set_register(int address, uint8_t value) {
write_phase_ = false; write_phase_ = false;
if(value & 0x80) { if(value & 0x80) {
if(is_sega_vdp(personality_)) { if(is_sega_vdp(personality_)) {
if(value & 0x40) { if(value & 0x40) {
master_system_.cram_is_selected = true; master_system_.cram_is_selected = true;
return; return;
} }
value &= 0xf; value &= 0xf;
} else { } else {
value &= 0x7; value &= 0x7;
} }
@ -602,6 +606,7 @@ void TMS9918::set_register(int address, uint8_t value) {
// A read request is enqueued upon setting the address; conversely a write // A read request is enqueued upon setting the address; conversely a write
// won't be enqueued unless and until some actual data is supplied. // won't be enqueued unless and until some actual data is supplied.
queued_access_ = MemoryAccess::Read; queued_access_ = MemoryAccess::Read;
cycles_until_access_ = vram_access_delay();
} }
master_system_.cram_is_selected = false; master_system_.cram_is_selected = false;
} }

View File

@ -36,7 +36,7 @@ enum class TVStandard {
NTSC NTSC
}; };
#define is_sega_vdp(x) x >= SMSVDP #define is_sega_vdp(x) ((x) >= SMSVDP)
class Base { class Base {
public: public:
@ -91,6 +91,14 @@ class Base {
enum class MemoryAccess { enum class MemoryAccess {
Read, Write, None Read, Write, None
} queued_access_ = MemoryAccess::None; } queued_access_ = MemoryAccess::None;
int cycles_until_access_ = 0;
int minimum_access_column_ = 0;
int vram_access_delay() {
// The Sega VDP seems to allow slightly quicker access;
// Sega types generally claim 26 Z80 cycles are sufficient.
// The received wisdom in MSX land is that it's 27.
return is_sega_vdp(personality_) ? 7 : 8;
}
// Holds the main status register. // Holds the main status register.
uint8_t status_ = 0; uint8_t status_ = 0;
@ -328,7 +336,11 @@ class Base {
} }
void do_external_slot(int access_column) { void do_external_slot(int access_column) {
// TODO: is queued access ready yet? // Don't do anything if the required time for the access to become executable
// has yet to pass.
if(access_column < minimum_access_column_) {
return;
}
switch(queued_access_) { switch(queued_access_) {
default: return; default: return;