mirror of
https://github.com/Gericom/GBARunner3.git
synced 2025-06-18 19:25:41 -04:00
Attempt to reenable and fix irq yielding
This commit is contained in:
parent
2414cf9d80
commit
d6086d4539
@ -57,7 +57,7 @@ INCLUDES := include source ../common ../../libs/mini-printf
|
||||
# options for code generation
|
||||
#---------------------------------------------------------------------------------
|
||||
ARCH := -marm -mthumb-interwork -march=armv5te -mtune=arm946e-s \
|
||||
-DLIBTWL_ARM9 -DARM9 #-DGBAR3_IRQ_YIELDING
|
||||
-DLIBTWL_ARM9 -DARM9 -DGBAR3_IRQ_YIELDING
|
||||
|
||||
CFLAGS := -g -Wall -O2\
|
||||
-fomit-frame-pointer\
|
||||
|
@ -29,42 +29,65 @@ u32 fs_waitForCompletion(FsWaitToken* waitToken, bool keepIrqsDisabled)
|
||||
{
|
||||
u32 irqs;
|
||||
#ifdef GBAR3_IRQ_YIELDING
|
||||
irqs = arm_disableIrqs();
|
||||
#endif
|
||||
while (true)
|
||||
if (gIrqYieldingEnabled)
|
||||
{
|
||||
#ifndef GBAR3_IRQ_YIELDING
|
||||
irqs = arm_disableIrqs();
|
||||
#endif
|
||||
if (waitToken && waitToken->transactionComplete)
|
||||
vm_disableIrqYielding();
|
||||
while (true)
|
||||
{
|
||||
break;
|
||||
if (waitToken && waitToken->transactionComplete)
|
||||
{
|
||||
break;
|
||||
}
|
||||
FsWaitToken* currentWaitToken = sCurrentWaitToken;
|
||||
if (!currentWaitToken)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (isArm7FsOperationComplete())
|
||||
{
|
||||
currentWaitToken->transactionComplete = true;
|
||||
sCurrentWaitToken = nullptr;
|
||||
break;
|
||||
}
|
||||
if (!(irqs & 0x80) && !vm_yieldGbaIrqs())
|
||||
{
|
||||
arm_restoreIrqs(irqs);
|
||||
irqs = arm_disableIrqs();
|
||||
}
|
||||
}
|
||||
FsWaitToken* currentWaitToken = sCurrentWaitToken;
|
||||
if (!currentWaitToken)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (isArm7FsOperationComplete())
|
||||
{
|
||||
currentWaitToken->transactionComplete = true;
|
||||
sCurrentWaitToken = nullptr;
|
||||
break;
|
||||
}
|
||||
#ifdef GBAR3_IRQ_YIELDING
|
||||
if (!(irqs & 0x80) && !vm_yieldGbaIrqs())
|
||||
{
|
||||
arm_restoreIrqs(irqs);
|
||||
irqs = arm_disableIrqs();
|
||||
}
|
||||
#else
|
||||
arm_restoreIrqs(irqs);
|
||||
#endif
|
||||
vm_restoreIrqYielding(true);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
irqs = arm_disableIrqs();
|
||||
if (waitToken && waitToken->transactionComplete)
|
||||
{
|
||||
break;
|
||||
}
|
||||
FsWaitToken* currentWaitToken = sCurrentWaitToken;
|
||||
if (!currentWaitToken)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (isArm7FsOperationComplete())
|
||||
{
|
||||
currentWaitToken->transactionComplete = true;
|
||||
sCurrentWaitToken = nullptr;
|
||||
break;
|
||||
}
|
||||
arm_restoreIrqs(irqs);
|
||||
}
|
||||
}
|
||||
|
||||
if (!keepIrqsDisabled)
|
||||
{
|
||||
arm_restoreIrqs(irqs);
|
||||
}
|
||||
|
||||
return irqs;
|
||||
}
|
||||
|
||||
|
@ -489,7 +489,7 @@ ITCM_CODE static void dmaStartImmediate(int channel, GbaDmaChannel* dmaIoBase, u
|
||||
src = src + ROM_LINEAR_GBA_ADDRESS - ROM_LINEAR_DS_ADDRESS;
|
||||
}
|
||||
u32 dst = dmaIoBase->dst;
|
||||
triggerDmaIrqIfEnabled(channel, control);
|
||||
bool irqYieldingState = vm_disableIrqYielding();
|
||||
if (channel == 3)
|
||||
{
|
||||
vm_enableNestedIrqs();
|
||||
@ -516,6 +516,8 @@ ITCM_CODE static void dmaStartImmediate(int channel, GbaDmaChannel* dmaIoBase, u
|
||||
{
|
||||
vm_disableNestedIrqs();
|
||||
}
|
||||
triggerDmaIrqIfEnabled(channel, control);
|
||||
vm_restoreIrqYielding(irqYieldingState);
|
||||
}
|
||||
|
||||
ITCM_CODE static void dmaStart(int channel, GbaDmaChannel* dmaIoBase, u32 control)
|
||||
|
@ -29,7 +29,8 @@ static u16 sCacheBlockToRomBlock[SDC_BLOCK_COUNT];
|
||||
/// total number of cache blocks when some blocks are permanently loaded.
|
||||
static u32 sBlockCount;
|
||||
|
||||
static u32 sTabuBlock;
|
||||
static u32 sTabuLevel;
|
||||
static u32 sTabuBlocks[2];
|
||||
vu32 gSdCacheIrqForbiddenRomBlockReplacementRange;
|
||||
|
||||
static DWORD sClusterTable[512];
|
||||
@ -43,12 +44,25 @@ static u32 getBlockToReplace(void)
|
||||
{
|
||||
sRandomState = sRandomState * 1566083941u + 2531011u;
|
||||
u32 maxPlusOne = sBlockCount;
|
||||
if (sTabuBlock != SDC_BLOCK_INVALID)
|
||||
if (sTabuBlocks[0] != SDC_BLOCK_INVALID)
|
||||
{
|
||||
maxPlusOne--;
|
||||
}
|
||||
if (sTabuLevel > 0 && sTabuBlocks[1] != SDC_BLOCK_INVALID)
|
||||
{
|
||||
maxPlusOne--;
|
||||
}
|
||||
u32 block = ((sRandomState >> 16) * maxPlusOne) >> 16;
|
||||
return block == sTabuBlock ? (sBlockCount - 1) : block;
|
||||
if (block == sTabuBlocks[0])
|
||||
{
|
||||
block = maxPlusOne;
|
||||
}
|
||||
else if (sTabuLevel > 0 && block == sTabuBlocks[1])
|
||||
{
|
||||
block = maxPlusOne + 1;
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static bool isCurrentlyFetching(void)
|
||||
@ -178,9 +192,11 @@ static void* loadRomBlock(u32 romBlock, u32 cacheBlock)
|
||||
sCurrentFetch.cacheBlock = cacheBlock;
|
||||
}
|
||||
|
||||
if ((arm_getCpsr() & 0x1F) != 0x12)
|
||||
bool decreaseTabuLevel = false;
|
||||
if ((arm_getCpsr() & 0x1F) != 0x12 && sTabuLevel < 2)
|
||||
{
|
||||
sTabuBlock = cacheBlock;
|
||||
sTabuBlocks[sTabuLevel++] = cacheBlock;
|
||||
decreaseTabuLevel = true;
|
||||
}
|
||||
|
||||
arm_restoreIrqs(irqs);
|
||||
@ -198,6 +214,11 @@ static void* loadRomBlock(u32 romBlock, u32 cacheBlock)
|
||||
fillOutOfBoundsCacheBlock(romBlock, cacheBlock);
|
||||
}
|
||||
|
||||
if (decreaseTabuLevel)
|
||||
{
|
||||
sTabuLevel--;
|
||||
}
|
||||
|
||||
return &sdc_cache[cacheBlock][0];
|
||||
}
|
||||
|
||||
@ -248,6 +269,10 @@ void sdc_init(void)
|
||||
sCurrentFetch.cacheBlock = SDC_BLOCK_INVALID;
|
||||
sCurrentFetch.romBlock = SDC_ROM_BLOCK_INVALID;
|
||||
gSdCacheIrqForbiddenRomBlockReplacementRange = 0;
|
||||
sTabuLevel = 0;
|
||||
sTabuBlocks[0] = SDC_BLOCK_INVALID;
|
||||
sTabuBlocks[1] = SDC_BLOCK_INVALID;
|
||||
gIrqYieldingEnabled = true;
|
||||
|
||||
sClusterTable[0] = sizeof(sClusterTable) / sizeof(DWORD);
|
||||
gFile.cltbl = sClusterTable;
|
||||
|
@ -4,9 +4,13 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern u32 gIrqYieldingEnabled;
|
||||
|
||||
extern void vm_enableNestedIrqs(void);
|
||||
extern void vm_disableNestedIrqs(void);
|
||||
extern bool vm_yieldGbaIrqs(void);
|
||||
extern bool vm_disableIrqYielding(void);
|
||||
extern void vm_restoreIrqYielding(bool isIrqYieldingEnabled);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -7,6 +7,10 @@
|
||||
#define IRQ_RETURN_FOR_NESTED_IRQ_ENABLE 0xE2 // always condition for subs pc, r13, #4
|
||||
#define IRQ_RETURN_FOR_NESTED_IRQ_DISABLE 0x92 // LS condition for sublss pc, r13, #4
|
||||
|
||||
.global gIrqYieldingEnabled
|
||||
gIrqYieldingEnabled:
|
||||
.word 0
|
||||
|
||||
nestedIrqLevel:
|
||||
.word 0
|
||||
|
||||
@ -52,6 +56,17 @@ arm_func vm_disableNestedIrqs
|
||||
yieldGbaIrqsGbaMode:
|
||||
swi 0x7F0000 // swiVMReturnFromYield
|
||||
|
||||
arm_func vm_disableIrqYielding
|
||||
mov r1, #0
|
||||
adr r2, gIrqYieldingEnabled
|
||||
swp r0, r1, [r2]
|
||||
bx lr
|
||||
|
||||
arm_func vm_restoreIrqYielding
|
||||
adr r1, gIrqYieldingEnabled
|
||||
str r0, [r1]
|
||||
bx lr
|
||||
|
||||
.section ".itcm", "ax"
|
||||
|
||||
arm_func vm_yieldGbaIrqs
|
||||
|
Loading…
Reference in New Issue
Block a user