1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-27 01:31:42 +00:00

Edge further towards actual fetching.

This commit is contained in:
Thomas Harte 2023-01-23 23:19:04 -05:00
parent 6b85ee9607
commit 445b34933a
2 changed files with 59 additions and 28 deletions

View File

@ -179,6 +179,8 @@ template <Personality personality> struct Storage<personality, std::enable_if_t<
enum class Type {
External,
DataBlock,
SpriteY,
SpriteContents,
} type = Type::External;
constexpr Event(int offset, Type type) noexcept :
@ -190,11 +192,20 @@ template <Personality personality> struct Storage<personality, std::enable_if_t<
constexpr Event() noexcept {}
};
// State that tracks fetching position within a line.
const Event *next_event_ = nullptr;
int data_block_ = 0;
int sprite_block_ = 0;
/// Resets line-ephemeral state for a new line.
void begin_line([[maybe_unused]] ScreenMode mode, bool is_refresh, [[maybe_unused]] bool sprites_enabled) {
// TODO: reinstate upon completion of the Yamaha pipeline.
// assert(mode < ScreenMode::YamahaText80 || next_event_ == nullptr || next_event_->offset == 1368);
data_block_ = 0;
sprite_block_ = 0;
if(is_refresh) {
next_event_ = refresh_events;
return;
@ -636,6 +647,7 @@ template <Personality personality> struct Base: public Storage<personality> {
template<bool use_end> void fetch_tms_character(int start, int end);
template<bool use_end> void fetch_yamaha(int start, int end);
template<ScreenMode> void fetch_yamaha(int end);
template<bool use_end> void fetch_sms(int start, int end);

View File

@ -470,38 +470,57 @@ template<bool use_end> void Base<personality>::fetch_sms(int start, int end) {
// MARK: - Yamaha
template <Personality personality>
template<ScreenMode mode> void Base<personality>::fetch_yamaha(int end) {
while(Storage<personality>::next_event_->offset < end) {
switch(Storage<personality>::next_event_->type) {
case Storage<personality>::Event::Type::External:
do_external_slot(Storage<personality>::next_event_->offset);
break;
case Storage<personality>::Event::Type::DataBlock: {
// Exactly how to fetch depends upon mode...
switch(mode) {
case ScreenMode::YamahaGraphics5: {
// TODO: work out start address as a function of fetch_pointer_.row, use current
// data block via data_block_, fetch data into line_buffers_[fetch_pointer_.row].bitmap.
} break;
default:
break;
}
++Storage<personality>::data_block_;
} break;
default: break;
}
++Storage<personality>::next_event_;
}
}
template <Personality personality>
template<bool use_end> void Base<personality>::fetch_yamaha([[maybe_unused]] int start, int end) {
if constexpr (is_yamaha_vdp(personality)) {
/*
Per http://map.grauw.nl/articles/vdp-vram-timing/vdp-timing.html :
The major change compared to the previous mode is that now the VDP needs to fetch extra data
for the bitmap rendering. These fetches happen in 32 blocks of 4 bytes (screen 5/6) or
8 bytes (screen 7/8). The fetches within one block happen in burst mode. This means that
one block takes 18 cycles (screen 5/6) or 20 cycles (screen 7/8). Though later we'll see
that the two spare cycles for screen 5/6 are not used for anything else, so for simplicity
we can say that in all bitmap modes a bitmap-fetch-block takes 20 cycles. This is even
clearer if you look at the RAS signal: this signal follows the exact same pattern in all
(bitmap) screen modes, so in screen 5/6 it remains active for two cycles longer than
strictly necessary.
Actually before these 32 blocks there's one extra dummy block. This block has the same timing
as the other blocks, but it always reads address 0x1FFFF. From an emulator point of view,
these dummy reads don't matter, it only matters that at those moments no other VRAM accesses
can occur.
*/
while(Storage<personality>::next_event_->offset < end) {
switch(Storage<personality>::next_event_->type) {
case Storage<personality>::Event::Type::External:
do_external_slot(Storage<personality>::next_event_->offset);
break;
default: break;
}
++Storage<personality>::next_event_;
// Dispatch according to [supported] screen mode.
#define Dispatch(mode) case mode: fetch_yamaha<mode>(end); break;
switch(screen_mode_) {
default: break;
Dispatch(ScreenMode::Blank);
Dispatch(ScreenMode::Text);
Dispatch(ScreenMode::MultiColour);
Dispatch(ScreenMode::ColouredText);
Dispatch(ScreenMode::Graphics);
Dispatch(ScreenMode::YamahaText80);
Dispatch(ScreenMode::YamahaGraphics3);
Dispatch(ScreenMode::YamahaGraphics4);
Dispatch(ScreenMode::YamahaGraphics5);
Dispatch(ScreenMode::YamahaGraphics6);
Dispatch(ScreenMode::YamahaGraphics7);
}
#undef Dispatch
}
}