HDMA: Set DoTransfer flag to true for all 8 HDMA channels during init if at least 1 HDMA channel is active (Fixed "Ladida_lol" test)
This commit is contained in:
parent
9d90fb9e52
commit
7bb0910607
1 changed files with 97 additions and 81 deletions
|
@ -98,17 +98,25 @@ void DmaController::RunDma(DmaChannelConfig &channel)
|
||||||
|
|
||||||
void DmaController::InitHdmaChannels()
|
void DmaController::InitHdmaChannels()
|
||||||
{
|
{
|
||||||
if(_hdmaChannels) {
|
for(int i = 0; i < 8; i++) {
|
||||||
|
//Reset internal flags on every frame, whether or not the channels are enabled
|
||||||
|
_channel[i].HdmaFinished = false;
|
||||||
|
_channel[i].DoTransfer = false; //not resetting this causes graphical glitches in some games (Aladdin, Super Ghouls and Ghosts)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!_hdmaChannels) {
|
||||||
|
//No channels are enabled, no more processing needs to be done
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//"The overhead is ~18 master cycles"
|
//"The overhead is ~18 master cycles"
|
||||||
_memoryManager->IncrementMasterClockValue<18>();
|
_memoryManager->IncrementMasterClockValue<18>();
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < 8; i++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
DmaChannelConfig &ch = _channel[i];
|
DmaChannelConfig &ch = _channel[i];
|
||||||
|
|
||||||
//Reset internal flags on every frame
|
//Set DoTransfer to true for all channels if any HDMA channel is enabled
|
||||||
ch.HdmaFinished = false;
|
ch.DoTransfer = true;
|
||||||
ch.DoTransfer = false; //not resetting this causes graphical glitches in some games (Aladdin, Super Ghouls and Ghosts)
|
|
||||||
|
|
||||||
if(_hdmaChannels & (1 << i)) {
|
if(_hdmaChannels & (1 << i)) {
|
||||||
//"1. Copy AAddress into Address."
|
//"1. Copy AAddress into Address."
|
||||||
|
@ -134,9 +142,6 @@ void DmaController::InitHdmaChannels()
|
||||||
//"plus 8 master cycles for each channel set for direct HDMA"
|
//"plus 8 master cycles for each channel set for direct HDMA"
|
||||||
_memoryManager->IncrementMasterClockValue<4>();
|
_memoryManager->IncrementMasterClockValue<4>();
|
||||||
}
|
}
|
||||||
|
|
||||||
//4. Set DoTransfer to true.
|
|
||||||
ch.DoTransfer = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -175,8 +180,10 @@ void DmaController::RunHdmaTransfer(DmaChannelConfig &channel)
|
||||||
|
|
||||||
void DmaController::ProcessHdmaChannels()
|
void DmaController::ProcessHdmaChannels()
|
||||||
{
|
{
|
||||||
bool needOverhead = true;
|
if(!_hdmaChannels) {
|
||||||
if(_hdmaChannels) {
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_hdmaPending = true;
|
_hdmaPending = true;
|
||||||
|
|
||||||
for(int i = 0; i < 8; i++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
|
@ -185,6 +192,8 @@ void DmaController::ProcessHdmaChannels()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Run all the DMA transfers for each channel first, before fetching data for the next scanline
|
||||||
|
bool needOverhead = true;
|
||||||
for(int i = 0; i < 8; i++) {
|
for(int i = 0; i < 8; i++) {
|
||||||
DmaChannelConfig &ch = _channel[i];
|
DmaChannelConfig &ch = _channel[i];
|
||||||
if((_hdmaChannels & (1 << i)) == 0 || ch.HdmaFinished) {
|
if((_hdmaChannels & (1 << i)) == 0 || ch.HdmaFinished) {
|
||||||
|
@ -205,6 +214,14 @@ void DmaController::ProcessHdmaChannels()
|
||||||
//2. For the number of bytes (1, 2, or 4) required for this Transfer Mode...
|
//2. For the number of bytes (1, 2, or 4) required for this Transfer Mode...
|
||||||
RunHdmaTransfer(ch);
|
RunHdmaTransfer(ch);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Update the channel's state & fetch data for the next scanline
|
||||||
|
for(int i = 0; i < 8; i++) {
|
||||||
|
DmaChannelConfig &ch = _channel[i];
|
||||||
|
if((_hdmaChannels & (1 << i)) == 0 || ch.HdmaFinished) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
//3. Decrement $43xA.
|
//3. Decrement $43xA.
|
||||||
ch.HdmaLineCounterAndRepeat--;
|
ch.HdmaLineCounterAndRepeat--;
|
||||||
|
@ -246,7 +263,6 @@ void DmaController::ProcessHdmaChannels()
|
||||||
|
|
||||||
//When DMA runs, the next instruction will not check the NMI/IRQ flags, which allows 2 instructions to run after DMA
|
//When DMA runs, the next instruction will not check the NMI/IRQ flags, which allows 2 instructions to run after DMA
|
||||||
_nmiIrqDelayCounter = 2;
|
_nmiIrqDelayCounter = 2;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DmaController::Write(uint16_t addr, uint8_t value)
|
void DmaController::Write(uint16_t addr, uint8_t value)
|
||||||
|
|
Loading…
Add table
Reference in a new issue