Change PLL disable method

This commit is contained in:
meepingsnesroms
2018-10-25 16:48:20 -07:00
parent f622aa8695
commit 74bc0b15f8
6 changed files with 44 additions and 37 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -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[];

View File

@@ -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){

View File

@@ -185,10 +185,6 @@ void m68328Execute(){
m68k_execute(cpuCycles);
addSysclks(sysclks);
//abort if PLL disabled
if(palmSysclksPerClk32 < 1.0)
break;
cyclesRemaining -= sysclks;
}