mirror of
https://github.com/libretro/Mu.git
synced 2026-09-22 22:56:12 +00:00
Change PLL disable method
This commit is contained in:
@@ -144,6 +144,7 @@ void emulatorExit(){
|
||||
void emulatorReset(){
|
||||
//reset doesnt clear RAM or SD card, all programs are stored in RAM or on SD card
|
||||
debugLog("Reset triggered, PC:0x%08X\n", m68k_get_reg(NULL, M68K_REG_PPC));
|
||||
blip_add_delta(palmAudioResampler, 0, -pwm1LastSampleDelta);
|
||||
m68328Reset();
|
||||
sed1376Reset();
|
||||
ads7846Reset();
|
||||
@@ -173,7 +174,8 @@ uint64_t emulatorGetStateSize(){
|
||||
size += sizeof(uint32_t) * 4 * CHIP_END;//chip select states
|
||||
size += sizeof(uint8_t) * 5 * CHIP_END;//chip select states
|
||||
size += sizeof(uint64_t) * 4;//32.32 fixed point double, timerXCycleCounter and CPU cycle timers
|
||||
size += sizeof(int32_t);//pllWakeWait
|
||||
size += sizeof(int8_t);//pllSleepWait
|
||||
size += sizeof(int8_t);//pllWakeWait
|
||||
size += sizeof(uint32_t);//clk32Counter
|
||||
size += sizeof(uint64_t);//pctlrCpuClockDivider
|
||||
size += sizeof(uint16_t) * 2;//timerStatusReadAcknowledge
|
||||
@@ -261,8 +263,10 @@ bool emulatorSaveState(buffer_t buffer){
|
||||
offset += sizeof(uint64_t);
|
||||
writeStateValueDouble(buffer.data + offset, palmCycleCounter);
|
||||
offset += sizeof(uint64_t);
|
||||
writeStateValueInt32(buffer.data + offset, pllWakeWait);
|
||||
offset += sizeof(int32_t);
|
||||
writeStateValueInt8(buffer.data + offset, pllSleepWait);
|
||||
offset += sizeof(int8_t);
|
||||
writeStateValueInt8(buffer.data + offset, pllWakeWait);
|
||||
offset += sizeof(int8_t);
|
||||
writeStateValueUint32(buffer.data + offset, clk32Counter);
|
||||
offset += sizeof(uint32_t);
|
||||
writeStateValueDouble(buffer.data + offset, pctlrCpuClockDivider);
|
||||
@@ -410,8 +414,10 @@ bool emulatorLoadState(buffer_t buffer){
|
||||
offset += sizeof(uint64_t);
|
||||
palmCycleCounter = readStateValueDouble(buffer.data + offset);
|
||||
offset += sizeof(uint64_t);
|
||||
pllWakeWait = readStateValueInt32(buffer.data + offset);
|
||||
offset += sizeof(int32_t);
|
||||
pllSleepWait = readStateValueInt8(buffer.data + offset);
|
||||
offset += sizeof(int8_t);
|
||||
pllWakeWait = readStateValueInt8(buffer.data + offset);
|
||||
offset += sizeof(int8_t);
|
||||
clk32Counter = readStateValueUint32(buffer.data + offset);
|
||||
offset += sizeof(uint32_t);
|
||||
pctlrCpuClockDivider = readStateValueDouble(buffer.data + offset);
|
||||
|
||||
@@ -114,7 +114,7 @@ typedef struct{
|
||||
|
||||
//config options
|
||||
#define EMU_FPS 60
|
||||
#define EMU_SYSCLK_PRECISION 200//the amount of cycles to run before adding SYSCLKs, higher = faster, higher values may skip timer events and lower audio accuracy
|
||||
#define EMU_SYSCLK_PRECISION 2000000//the amount of cycles to run before adding SYSCLKs, higher = faster, higher values may skip timer events and lower audio accuracy
|
||||
#define AUDIO_SAMPLE_RATE 48000
|
||||
#define SAVE_STATE_VERSION 0
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
|
||||
chip_t chips[CHIP_END];
|
||||
int32_t pllWakeWait;
|
||||
int8_t pllSleepWait;
|
||||
int8_t pllWakeWait;
|
||||
uint32_t clk32Counter;
|
||||
double pctlrCpuClockDivider;
|
||||
double timerCycleCounter[2];
|
||||
@@ -47,7 +48,7 @@ static int32_t audioGetFramePercentage();
|
||||
#include "hardwareRegistersTiming.c.h"
|
||||
|
||||
bool pllIsOn(){
|
||||
return !(registerArrayRead16(PLLCR) & 0x0008);
|
||||
return !(palmSysclksPerClk32 < 1.0);
|
||||
}
|
||||
|
||||
bool backlightAmplifierState(){
|
||||
@@ -120,7 +121,7 @@ void setWriteProtectViolation(uint32_t address){
|
||||
static void pllWakeCpuIfOff(){
|
||||
if(!pllIsOn() && pllWakeWait == -1){
|
||||
//PLL is off and not already in the process of waking up
|
||||
uint8_t pllWaitTable[4] = {32, 48, 64, 96};
|
||||
int8_t pllWaitTable[4] = {32, 48, 64, 96};
|
||||
pllWakeWait = pllWaitTable[registerArrayRead16(PLLCR) & 0x0003];
|
||||
}
|
||||
}
|
||||
@@ -817,11 +818,10 @@ void setHwRegister16(uint32_t address, uint16_t value){
|
||||
palmSysclksPerClk32 = sysclksPerClk32();
|
||||
setSed1376Attached(sed1376ClockConnected());
|
||||
|
||||
if(value & 0x0008){
|
||||
//The PLL shuts down 30 clock cycles of SYSCLK after the DISPLL bit is set in the PLLCR
|
||||
m68k_modify_timeslice(-m68k_cycles_remaining() + 30);
|
||||
debugLog("Disable PLL set, CPU off in 30 cycles!\n");
|
||||
}
|
||||
if(value & 0x0008)
|
||||
pllSleepWait = 30;//The PLL shuts down 30 clocks of CLK32 after the DISPLL bit is set in the PLLCR
|
||||
else
|
||||
pllSleepWait = -1;//allow the CPU to cancel the shut down
|
||||
break;
|
||||
|
||||
case ICR:
|
||||
@@ -1065,6 +1065,7 @@ void resetHwRegisters(){
|
||||
palmSysclksPerClk32 = 0.0;
|
||||
clk32Counter = 0;
|
||||
pctlrCpuClockDivider = 1.0;
|
||||
pllSleepWait = -1;
|
||||
pllWakeWait = -1;
|
||||
timerCycleCounter[0] = 0.0;
|
||||
timerCycleCounter[1] = 0.0;
|
||||
|
||||
@@ -63,7 +63,8 @@ typedef struct{
|
||||
|
||||
//variables
|
||||
extern chip_t chips[];
|
||||
extern int32_t pllWakeWait;
|
||||
extern int8_t pllSleepWait;
|
||||
extern int8_t pllWakeWait;
|
||||
extern uint32_t clk32Counter;
|
||||
extern double pctlrCpuClockDivider;
|
||||
extern double timerCycleCounter[];
|
||||
|
||||
@@ -137,26 +137,19 @@ static void timer2(uint8_t reason, double sysclks){
|
||||
}
|
||||
|
||||
static double dmaclksPerClk32(){
|
||||
double dmaclks;
|
||||
uint16_t pllcr = registerArrayRead16(PLLCR);
|
||||
uint16_t pllfsr = registerArrayRead16(PLLFSR);
|
||||
uint8_t p = pllfsr & 0x00FF;
|
||||
uint8_t q = pllfsr >> 8 & 0x000F;
|
||||
double dmaclks = 2.0 * (14.0 * (p + 1.0) + q + 1.0);
|
||||
|
||||
if(pllIsOn()){
|
||||
uint16_t pllcr = registerArrayRead16(PLLCR);
|
||||
uint16_t pllfsr = registerArrayRead16(PLLFSR);
|
||||
uint8_t p = pllfsr & 0x00FF;
|
||||
uint8_t q = pllfsr >> 8 & 0x000F;
|
||||
dmaclks = 2.0 * (14.0 * (p + 1.0) + q + 1.0);
|
||||
//prescaler 1 enabled, divide by 2
|
||||
if(pllcr & 0x0080)
|
||||
dmaclks /= 2.0;
|
||||
|
||||
//prescaler 1 enabled, divide by 2
|
||||
if(pllcr & 0x0080)
|
||||
dmaclks /= 2.0;
|
||||
|
||||
//prescaler 2 enabled, divides value from prescaler 1 by 2
|
||||
if(pllcr & 0x0020)
|
||||
dmaclks /= 2.0;
|
||||
}
|
||||
else{
|
||||
dmaclks = 0.0;
|
||||
}
|
||||
//prescaler 2 enabled, divides value from prescaler 1 by 2
|
||||
if(pllcr & 0x0020)
|
||||
dmaclks /= 2.0;
|
||||
|
||||
return dmaclks;
|
||||
}
|
||||
@@ -331,6 +324,16 @@ void endClk32(){
|
||||
timer2(TIMER_REASON_CLK32, 0);
|
||||
samplePwm1(true/*forClk32*/, 0.0);
|
||||
|
||||
//PLLCR sleep wait
|
||||
if(pllSleepWait != -1){
|
||||
if(pllSleepWait == 0){
|
||||
//disable PLL and CPU
|
||||
palmSysclksPerClk32 = 0.0;
|
||||
debugLog("PLL disabled, CPU is off!\n");
|
||||
}
|
||||
pllSleepWait--;
|
||||
}
|
||||
|
||||
//PLLCR wake select wait
|
||||
if(pllWakeWait != -1){
|
||||
if(pllWakeWait == 0){
|
||||
|
||||
@@ -185,10 +185,6 @@ void m68328Execute(){
|
||||
m68k_execute(cpuCycles);
|
||||
addSysclks(sysclks);
|
||||
|
||||
//abort if PLL disabled
|
||||
if(palmSysclksPerClk32 < 1.0)
|
||||
break;
|
||||
|
||||
cyclesRemaining -= sysclks;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user