mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-20 14:29:11 +00:00
Simplify sprite state machine.
This now better matches the explanation given on Page 133 of the Amiga System Programmer's Guide.
This commit is contained in:
parent
610c85a354
commit
276cbfa505
@ -1111,60 +1111,51 @@ void Chipset::Sprite::set_stop_and_control(uint16_t value) {
|
|||||||
v_stop_ = uint16_t((value >> 8) | ((value & 0x02) << 7));
|
v_stop_ = uint16_t((value >> 8) | ((value & 0x02) << 7));
|
||||||
v_start_ = uint16_t((v_start_ & 0x00ff) | ((value & 0x04) << 6));
|
v_start_ = uint16_t((v_start_ & 0x00ff) | ((value & 0x04) << 6));
|
||||||
attached = value & 0x80;
|
attached = value & 0x80;
|
||||||
visible = active_ = false; // 'Disarm' the sprite.
|
visible = false; // 'Disarm' the sprite.
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chipset::Sprite::set_image_data(int slot, uint16_t value) {
|
void Chipset::Sprite::set_image_data(int slot, uint16_t value) {
|
||||||
data[slot] = value;
|
data[slot] = value;
|
||||||
active_ |= slot == 0;
|
visible |= slot == 0;
|
||||||
visible = active_ && vertical_in_range_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Chipset::Sprite::advance_dma(int y) {
|
bool Chipset::Sprite::advance_dma(int y) {
|
||||||
|
visible |= (y == v_start_);
|
||||||
|
if(y == v_stop_) {
|
||||||
|
dma_state_ = DMAState::FetchStart;
|
||||||
|
}
|
||||||
|
if(!visible) return false;
|
||||||
|
|
||||||
|
// Fetch another word.
|
||||||
|
const uint16_t next_word = ram_[pointer_[0] & ram_mask_];
|
||||||
|
++pointer_[0];
|
||||||
|
|
||||||
|
// Put the fetched word somewhere appropriate and update the DMA state.
|
||||||
switch(dma_state_) {
|
switch(dma_state_) {
|
||||||
// i.e. stopped.
|
// i.e. stopped.
|
||||||
default: return false;
|
default: return false;
|
||||||
|
|
||||||
// FetchStart: fetch the first control word and proceed to the second.
|
// FetchStart: fetch the first control word and proceed to the second.
|
||||||
case DMAState::FetchStart:
|
case DMAState::FetchStart:
|
||||||
set_start_position(ram_[pointer_[0] & ram_mask_]);
|
set_start_position(next_word);
|
||||||
++pointer_[0];
|
|
||||||
dma_state_ = DMAState::FetchStopAndControl;
|
dma_state_ = DMAState::FetchStopAndControl;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// FetchStopAndControl: fetch second control word and wait for V start.
|
// FetchStopAndControl: fetch second control word, which will automatically disable visibility.
|
||||||
case DMAState::FetchStopAndControl:
|
case DMAState::FetchStopAndControl:
|
||||||
set_stop_and_control(ram_[pointer_[0] & ram_mask_]);
|
set_stop_and_control(next_word);
|
||||||
++pointer_[0];
|
dma_state_ = DMAState::FetchData1;
|
||||||
dma_state_ = DMAState::WaitingForStart;
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// WaitingForStart: repeat until V start is found.
|
// FetchData1: Just fetch a word and proceed to FetchData0.
|
||||||
case DMAState::WaitingForStart:
|
|
||||||
if(y != v_start_) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
vertical_in_range_ = true;
|
|
||||||
visible = active_;
|
|
||||||
[[fallthrough]];
|
|
||||||
|
|
||||||
// FetchData1: if v end is reached, stop DMA. Otherwise fetch a word
|
|
||||||
// and proceed to FetchData0.
|
|
||||||
case DMAState::FetchData1:
|
case DMAState::FetchData1:
|
||||||
if(y == v_stop_) {
|
set_image_data(1, next_word);
|
||||||
dma_state_ = DMAState::FetchStart;
|
|
||||||
visible = vertical_in_range_ = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
set_image_data(1, ram_[pointer_[0] & ram_mask_]);
|
|
||||||
++pointer_[0];
|
|
||||||
dma_state_ = DMAState::FetchData0;
|
dma_state_ = DMAState::FetchData0;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// FetchData0: fetch a word and proceed back to FetchData1.
|
// FetchData0: fetch a word and return to FetchData1.
|
||||||
case DMAState::FetchData0:
|
case DMAState::FetchData0:
|
||||||
set_image_data(0, ram_[pointer_[0] & ram_mask_]);
|
set_image_data(0, next_word);
|
||||||
++pointer_[0];
|
|
||||||
dma_state_ = DMAState::FetchData1;
|
dma_state_ = DMAState::FetchData1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -160,14 +160,10 @@ class Chipset: private ClockingHint::Observer {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
uint16_t v_start_ = 0, v_stop_ = 0;
|
uint16_t v_start_ = 0, v_stop_ = 0;
|
||||||
bool active_ = false;
|
|
||||||
bool vertical_in_range_ = false;
|
|
||||||
|
|
||||||
enum class DMAState {
|
enum class DMAState {
|
||||||
Stopped,
|
|
||||||
FetchStart,
|
FetchStart,
|
||||||
FetchStopAndControl,
|
FetchStopAndControl,
|
||||||
WaitingForStart,
|
|
||||||
|
|
||||||
FetchData1,
|
FetchData1,
|
||||||
FetchData0,
|
FetchData0,
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
</Testables>
|
</Testables>
|
||||||
</TestAction>
|
</TestAction>
|
||||||
<LaunchAction
|
<LaunchAction
|
||||||
buildConfiguration = "Debug"
|
buildConfiguration = "Release"
|
||||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
enableASanStackUseAfterReturn = "YES"
|
enableASanStackUseAfterReturn = "YES"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user