1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-21 21:33:54 +00:00

Carries through paging state; avoids file rereads.

This commit is contained in:
Thomas Harte 2021-04-25 20:46:49 -04:00
parent c34cb310a8
commit 5e08d7db39
3 changed files with 37 additions and 11 deletions

View File

@ -20,13 +20,27 @@ namespace ZXSpectrum {
struct State: public Reflection::StructImpl<State> {
CPU::Z80::State z80;
Video::State video;
// In 16kb or 48kb mode, RAM will be 16kb or 48kb and represent
// memory in standard linear order. In 128kb mode, RAM will be
// 128kb with the first 16kb representing bank 0, the next bank 1, etc.
std::vector<uint8_t> ram;
// Meaningful for 128kb machines only.
uint8_t last_7ffd = 0;
uint8_t last_fffd = 0;
// Meaningful for the +2a and +3 only.
uint8_t last_1ffd = 0;
State() {
if(needs_declare()) {
DeclareField(z80);
DeclareField(video);
DeclareField(ram);
DeclareField(last_7ffd);
DeclareField(last_fffd);
DeclareField(last_1ffd);
}
}
};

View File

@ -138,6 +138,12 @@ template<Model model> class ConcreteMachine:
}
} else {
memcpy(ram_.data(), state->ram.data(), std::min(ram_.size(), state->ram.size()));
port1ffd_ = state->last_1ffd;
port7ffd_ = state->last_7ffd;
update_memory_map();
GI::AY38910::Utility::select_register(ay_, state->last_fffd);
}
}
}
@ -400,10 +406,6 @@ template<Model model> class ConcreteMachine:
// Set the proper video base pointer.
set_video_address();
// Potentially lock paging, _after_ the current
// port values have taken effect.
disable_paging_ |= *cycle.value & 0x20;
}
// Test for +2a/+3 paging (i.e. port 1ffd).
@ -729,6 +731,10 @@ template<Model model> class ConcreteMachine:
set_memory(2, 2);
set_memory(3, port7ffd_ & 7);
}
// Potentially lock paging, _after_ the current
// port values have taken effect.
disable_paging_ = port7ffd_ & 0x20;
}
void set_memory(int bank, uint8_t source) {

View File

@ -28,20 +28,25 @@ std::vector<uint8_t> read_memory(Storage::FileHolder &file, size_t size, bool is
while(cursor != size) {
const uint8_t next = file.get8();
if(next != 0xed) {
// If the next byte definitely doesn't, or can't,
// start an ED ED sequence then just take it.
if(next != 0xed || cursor == size - 1) {
result[cursor] = next;
++cursor;
continue;
}
// Grab the next byte. If it's not ED then write
// both and continue.
const uint8_t after = file.get8();
if(after != 0xed) {
result[cursor] = next;
++cursor;
file.seek(-1, SEEK_CUR);
result[cursor+1] = after;
cursor += 2;
continue;
}
// An ED ED has begun, so grab the RLE sequence.
const uint8_t count = file.get8();
const uint8_t value = file.get8();
@ -112,7 +117,8 @@ std::unique_ptr<Analyser::Static::Target> Z80::load(const std::string &file_name
}
state->z80.registers.program_counter = file.get16le();
switch(file.get8()) {
const uint8_t model = file.get8();
switch(model) {
default: return nullptr;
case 0: result->model = Target::Model::FortyEightK; break;
case 3: result->model = Target::Model::OneTwoEightK; break;
@ -122,7 +128,7 @@ std::unique_ptr<Analyser::Static::Target> Z80::load(const std::string &file_name
case 13: result->model = Target::Model::Plus2a; break;
}
const uint8_t last7ffd = file.get8(); (void)last7ffd; // TODO
state->last_7ffd = file.get8();
file.seek(1, SEEK_CUR);
if(file.get8() & 0x80) {
@ -135,7 +141,7 @@ std::unique_ptr<Analyser::Static::Target> Z80::load(const std::string &file_name
}
}
const uint8_t lastfffd = file.get8(); (void)lastfffd; // TODO
state->last_fffd = file.get8();
file.seek(16, SEEK_CUR); // Sound chip registers: TODO.
if(bonus_header_size != 23) {
@ -165,7 +171,7 @@ std::unique_ptr<Analyser::Static::Target> Z80::load(const std::string &file_name
file.seek(3, SEEK_CUR);
if(bonus_header_size == 55) {
const uint8_t last1ffd = file.get8(); (void)last1ffd; // TODO
state->last_1ffd = file.get8();
}
}