Fix lockups in 68K Palm OS

This commit is contained in:
meepingsnesroms
2019-11-27 14:39:55 -08:00
parent 865b1d5f86
commit f66e5613b3
5 changed files with 24 additions and 27 deletions

View File

@@ -1,3 +1,5 @@
T3 locks up endlessly checking TSC2101 interrupts
Randomly locks up for 1-2 seconds(this seems to have t do with the audio bug in applications where pushing the app category selector then white space will make a shorter or longer beep than it should, also lock ups occur in galax when sound plays)(Started somewhere between June 9 2019 and June 20 2019, right after all the UART stuff)
QT release build is broken
QT release build is broken
Fixed:
68K Palm OS randomly locks up for 1-2 seconds(caused by interrupt handling code not turning the CPU back on for masked interrupts when it should because of faulty interrupt cacheing, Caused by commit: 1567cbce674741bc13be92b0847f59a5cc68335a)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 275 KiB

View File

@@ -26,7 +26,6 @@ add Palm Tungsten T3 support
v1.0.0 to v1.1.0(Feb 25 2019 - Christmas 2019)
RetroArch GUI:
*allow mouse cursor to be rendered with multiple CPUs(removed for now)
*now launches content like cartridge based systems
*make default button layout match default controller layout better
*allow disabling the silkscreen area

View File

@@ -23,7 +23,6 @@ uint16_t* dbvzFramebuffer;
uint16_t dbvzFramebufferWidth;
uint16_t dbvzFramebufferHeight;
static bool dbvzInterruptChanged;//reduces time wasted on checking interrupts that where updated to a new value identical to the old one, does not need to be in states
static double dbvzSysclksPerClk32;//how many SYSCLK cycles before toggling the 32.768 kHz crystal
static uint32_t dbvzFrameClk32s;//how many CLK32s have happened in the current frame
static double dbvzClk32Sysclks;//how many SYSCLKs have happened in the current CLK32
@@ -237,6 +236,9 @@ static void pllWakeCpuIfOff(void){
}
static void checkInterrupts(void){
//reduces time wasted on checking interrupts that where updated to a new value identical to the old one, does not need to be in states
static uint32_t dbvzCachedInterrupts;
uint32_t activeInterrupts = registerArrayRead32(ISR);
uint16_t interruptLevelControlRegister = registerArrayRead16(ILCR);
uint8_t spi1IrqLevel = interruptLevelControlRegister >> 12;
@@ -245,8 +247,14 @@ static void checkInterrupts(void){
uint8_t timer2IrqLevel = interruptLevelControlRegister & 0x0007;
uint8_t intLevel = 0;
//even masked interrupts turn off PCTLR, 4.5.4 Power Control Register MC68VZ328UM.pdf
if(registerArrayRead32(IPR) && registerArrayRead8(PCTLR) & 0x80){
registerArrayWrite8(PCTLR, registerArrayRead8(PCTLR) & 0x1F);
pctlrCpuClockDivider = 1.0;
}
//dont waste time if nothing changed
if(!dbvzInterruptChanged)
if(activeInterrupts == dbvzCachedInterrupts)
return;
//static interrupts
@@ -284,17 +292,11 @@ static void checkInterrupts(void){
if(intLevel < timer2IrqLevel && activeInterrupts & DBVZ_INT_TMR2)
intLevel = timer2IrqLevel;
//even masked interrupts turn off PCTLR, 4.5.4 Power Control Register MC68VZ328UM.pdf
if(intLevel > 0 && registerArrayRead8(PCTLR) & 0x80){
registerArrayWrite8(PCTLR, registerArrayRead8(PCTLR) & 0x1F);
pctlrCpuClockDivider = 1.0;
}
//should be called even if intLevel is 0, that is how the interrupt state gets cleared
flx68000SetIrq(intLevel);
//no interrupts have changed since the last call to this function, which is now
dbvzInterruptChanged = false;
dbvzCachedInterrupts = activeInterrupts;
}
static void checkPortDInterrupts(void){
@@ -426,6 +428,7 @@ uint8_t dbvzGetRegister8(uint32_t address){
case LCKCON:
case IVR:
case PWMP1:
case LGPMR:
//LCD controller
case LPICF:
@@ -684,6 +687,7 @@ void dbvzSetRegister8(uint32_t address, uint8_t value){
registerArrayWrite8(address, value & 0x9F);
if(value & 0x80)
pctlrCpuClockDivider = (value & 0x1F) / 31.0;
checkInterrupts();//may need to turn PCTLR off right after its turned on(could be in an interrupt)
return;
case IVR:
@@ -860,14 +864,12 @@ void dbvzSetRegister16(uint32_t address, uint16_t value){
//this is a 32 bit register but Palm OS writes to it as 16 bit chunks
registerArrayWrite16(IMR, value & 0x00FF);
registerArrayWrite16(ISR, registerArrayRead16(IPR) & ~registerArrayRead16(IMR));
dbvzInterruptChanged |= true;
checkInterrupts();
return;
case IMR + 2:
//this is a 32 bit register but Palm OS writes to it as 16 bit chunks
registerArrayWrite16(IMR + 2, value & 0xFFFF);//Palm OS writes to reserved bits 14 and 15
registerArrayWrite16(ISR + 2, registerArrayRead16(IPR + 2) & ~registerArrayRead16(IMR + 2));
dbvzInterruptChanged |= true;
checkInterrupts();
return;
@@ -1228,7 +1230,6 @@ void dbvzSetRegister32(uint32_t address, uint32_t value){
case IMR:
registerArrayWrite32(IMR, value & 0x00FFFFFF);//Palm OS writes to reserved bits 14 and 15
registerArrayWrite32(ISR, registerArrayRead32(IPR) & ~registerArrayRead32(IMR));
dbvzInterruptChanged |= true;
checkInterrupts();
return;
@@ -1252,7 +1253,6 @@ void dbvzReset(void){
uint32_t oldRtc = registerArrayRead32(RTCTIME);//preserve RTCTIME
uint16_t oldDayr = registerArrayRead16(DAYR);//preserve DAYR
dbvzInterruptChanged = false;//speed hack variable
memset(dbvzReg, 0x00, DBVZ_REG_SIZE - DBVZ_BOOTLOADER_SIZE);
dbvzSysclksPerClk32 = 0.0;
clk32Counter = 0;
@@ -1402,6 +1402,7 @@ void dbvzReset(void){
dbvzSysclksPerClk32 = sysclksPerClk32();
dbvzResetAddressSpace();
checkInterrupts();
flx68000Reset();
}

View File

@@ -20,19 +20,15 @@ static void registerArrayWrite32(uint32_t address, uint32_t value){M68K_BUFFER_W
//interrupt setters, used for setting an interrupt with masking by IMR and logging in IPR
static void setIprIsrBit(uint32_t interruptBit){
uint32_t ipr = registerArrayRead32(IPR);
dbvzInterruptChanged |= !(ipr & interruptBit);
ipr |= interruptBit;
registerArrayWrite32(IPR, ipr);
registerArrayWrite32(ISR, ipr & ~registerArrayRead32(IMR));
uint32_t newIpr = registerArrayRead32(IPR) | interruptBit;
registerArrayWrite32(IPR, newIpr);
registerArrayWrite32(ISR, newIpr & ~registerArrayRead32(IMR));
}
static void clearIprIsrBit(uint32_t interruptBit){
uint32_t ipr = registerArrayRead32(IPR);
dbvzInterruptChanged |= !!(ipr & interruptBit);
ipr &= ~interruptBit;
registerArrayWrite32(IPR, ipr);
registerArrayWrite32(ISR, ipr & ~registerArrayRead32(IMR));
uint32_t newIpr = registerArrayRead32(IPR) & ~interruptBit;
registerArrayWrite32(IPR, newIpr);
registerArrayWrite32(ISR, newIpr & ~registerArrayRead32(IMR));
}
//SPI1 FIFO accessors
@@ -815,7 +811,6 @@ static void setIsr(uint32_t value, bool useTopWord, bool useBottomWord){
registerArrayWrite16(ISR + 2, registerArrayRead16(ISR + 2) & ~(value & 0xFFFF & portDEdgeSelect << 8));
}
dbvzInterruptChanged |= true;
checkInterrupts();
}