Skip to content

Commit f66e561

Browse files
Fix lockups in 68K Palm OS
1 parent 865b1d5 commit f66e561

File tree

5 files changed

+24
-27
lines changed

5 files changed

+24
-27
lines changed

bugs/currentBug.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
T3 locks up endlessly checking TSC2101 interrupts
2-
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)
3-
QT release build is broken
2+
QT release build is broken
3+
4+
Fixed:
5+
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)

bugs/lockUpBug.png

-275 KB
Binary file not shown.

roadmap.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ add Palm Tungsten T3 support
2626
v1.0.0 to v1.1.0(Feb 25 2019 - Christmas 2019)
2727

2828
RetroArch GUI:
29-
*allow mouse cursor to be rendered with multiple CPUs(removed for now)
3029
*now launches content like cartridge based systems
3130
*make default button layout match default controller layout better
3231
*allow disabling the silkscreen area

src/dbvz.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ uint16_t* dbvzFramebuffer;
2323
uint16_t dbvzFramebufferWidth;
2424
uint16_t dbvzFramebufferHeight;
2525

26-
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
2726
static double dbvzSysclksPerClk32;//how many SYSCLK cycles before toggling the 32.768 kHz crystal
2827
static uint32_t dbvzFrameClk32s;//how many CLK32s have happened in the current frame
2928
static double dbvzClk32Sysclks;//how many SYSCLKs have happened in the current CLK32
@@ -237,6 +236,9 @@ static void pllWakeCpuIfOff(void){
237236
}
238237

239238
static void checkInterrupts(void){
239+
//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
240+
static uint32_t dbvzCachedInterrupts;
241+
240242
uint32_t activeInterrupts = registerArrayRead32(ISR);
241243
uint16_t interruptLevelControlRegister = registerArrayRead16(ILCR);
242244
uint8_t spi1IrqLevel = interruptLevelControlRegister >> 12;
@@ -245,8 +247,14 @@ static void checkInterrupts(void){
245247
uint8_t timer2IrqLevel = interruptLevelControlRegister & 0x0007;
246248
uint8_t intLevel = 0;
247249

250+
//even masked interrupts turn off PCTLR, 4.5.4 Power Control Register MC68VZ328UM.pdf
251+
if(registerArrayRead32(IPR) && registerArrayRead8(PCTLR) & 0x80){
252+
registerArrayWrite8(PCTLR, registerArrayRead8(PCTLR) & 0x1F);
253+
pctlrCpuClockDivider = 1.0;
254+
}
255+
248256
//dont waste time if nothing changed
249-
if(!dbvzInterruptChanged)
257+
if(activeInterrupts == dbvzCachedInterrupts)
250258
return;
251259

252260
//static interrupts
@@ -284,17 +292,11 @@ static void checkInterrupts(void){
284292
if(intLevel < timer2IrqLevel && activeInterrupts & DBVZ_INT_TMR2)
285293
intLevel = timer2IrqLevel;
286294

287-
//even masked interrupts turn off PCTLR, 4.5.4 Power Control Register MC68VZ328UM.pdf
288-
if(intLevel > 0 && registerArrayRead8(PCTLR) & 0x80){
289-
registerArrayWrite8(PCTLR, registerArrayRead8(PCTLR) & 0x1F);
290-
pctlrCpuClockDivider = 1.0;
291-
}
292-
293295
//should be called even if intLevel is 0, that is how the interrupt state gets cleared
294296
flx68000SetIrq(intLevel);
295297

296298
//no interrupts have changed since the last call to this function, which is now
297-
dbvzInterruptChanged = false;
299+
dbvzCachedInterrupts = activeInterrupts;
298300
}
299301

300302
static void checkPortDInterrupts(void){
@@ -426,6 +428,7 @@ uint8_t dbvzGetRegister8(uint32_t address){
426428
case LCKCON:
427429
case IVR:
428430
case PWMP1:
431+
case LGPMR:
429432

430433
//LCD controller
431434
case LPICF:
@@ -684,6 +687,7 @@ void dbvzSetRegister8(uint32_t address, uint8_t value){
684687
registerArrayWrite8(address, value & 0x9F);
685688
if(value & 0x80)
686689
pctlrCpuClockDivider = (value & 0x1F) / 31.0;
690+
checkInterrupts();//may need to turn PCTLR off right after its turned on(could be in an interrupt)
687691
return;
688692

689693
case IVR:
@@ -860,14 +864,12 @@ void dbvzSetRegister16(uint32_t address, uint16_t value){
860864
//this is a 32 bit register but Palm OS writes to it as 16 bit chunks
861865
registerArrayWrite16(IMR, value & 0x00FF);
862866
registerArrayWrite16(ISR, registerArrayRead16(IPR) & ~registerArrayRead16(IMR));
863-
dbvzInterruptChanged |= true;
864867
checkInterrupts();
865868
return;
866869
case IMR + 2:
867870
//this is a 32 bit register but Palm OS writes to it as 16 bit chunks
868871
registerArrayWrite16(IMR + 2, value & 0xFFFF);//Palm OS writes to reserved bits 14 and 15
869872
registerArrayWrite16(ISR + 2, registerArrayRead16(IPR + 2) & ~registerArrayRead16(IMR + 2));
870-
dbvzInterruptChanged |= true;
871873
checkInterrupts();
872874
return;
873875

@@ -1228,7 +1230,6 @@ void dbvzSetRegister32(uint32_t address, uint32_t value){
12281230
case IMR:
12291231
registerArrayWrite32(IMR, value & 0x00FFFFFF);//Palm OS writes to reserved bits 14 and 15
12301232
registerArrayWrite32(ISR, registerArrayRead32(IPR) & ~registerArrayRead32(IMR));
1231-
dbvzInterruptChanged |= true;
12321233
checkInterrupts();
12331234
return;
12341235

@@ -1252,7 +1253,6 @@ void dbvzReset(void){
12521253
uint32_t oldRtc = registerArrayRead32(RTCTIME);//preserve RTCTIME
12531254
uint16_t oldDayr = registerArrayRead16(DAYR);//preserve DAYR
12541255

1255-
dbvzInterruptChanged = false;//speed hack variable
12561256
memset(dbvzReg, 0x00, DBVZ_REG_SIZE - DBVZ_BOOTLOADER_SIZE);
12571257
dbvzSysclksPerClk32 = 0.0;
12581258
clk32Counter = 0;
@@ -1402,6 +1402,7 @@ void dbvzReset(void){
14021402
dbvzSysclksPerClk32 = sysclksPerClk32();
14031403

14041404
dbvzResetAddressSpace();
1405+
checkInterrupts();
14051406
flx68000Reset();
14061407
}
14071408

src/dbvzRegisterAccessors.c.h

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,15 @@ static void registerArrayWrite32(uint32_t address, uint32_t value){M68K_BUFFER_W
2020

2121
//interrupt setters, used for setting an interrupt with masking by IMR and logging in IPR
2222
static void setIprIsrBit(uint32_t interruptBit){
23-
uint32_t ipr = registerArrayRead32(IPR);
24-
dbvzInterruptChanged |= !(ipr & interruptBit);
25-
ipr |= interruptBit;
26-
registerArrayWrite32(IPR, ipr);
27-
registerArrayWrite32(ISR, ipr & ~registerArrayRead32(IMR));
23+
uint32_t newIpr = registerArrayRead32(IPR) | interruptBit;
24+
registerArrayWrite32(IPR, newIpr);
25+
registerArrayWrite32(ISR, newIpr & ~registerArrayRead32(IMR));
2826
}
2927

3028
static void clearIprIsrBit(uint32_t interruptBit){
31-
uint32_t ipr = registerArrayRead32(IPR);
32-
dbvzInterruptChanged |= !!(ipr & interruptBit);
33-
ipr &= ~interruptBit;
34-
registerArrayWrite32(IPR, ipr);
35-
registerArrayWrite32(ISR, ipr & ~registerArrayRead32(IMR));
29+
uint32_t newIpr = registerArrayRead32(IPR) & ~interruptBit;
30+
registerArrayWrite32(IPR, newIpr);
31+
registerArrayWrite32(ISR, newIpr & ~registerArrayRead32(IMR));
3632
}
3733

3834
//SPI1 FIFO accessors
@@ -815,7 +811,6 @@ static void setIsr(uint32_t value, bool useTopWord, bool useBottomWord){
815811
registerArrayWrite16(ISR + 2, registerArrayRead16(ISR + 2) & ~(value & 0xFFFF & portDEdgeSelect << 8));
816812
}
817813

818-
dbvzInterruptChanged |= true;
819814
checkInterrupts();
820815
}
821816

0 commit comments

Comments
 (0)