diff --git a/src/emulator.c b/src/emulator.c index 6f21d5f..d4378d8 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -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); diff --git a/src/emulator.h b/src/emulator.h index 4c3efb6..2c4701b 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -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 diff --git a/src/hardwareRegisters.c b/src/hardwareRegisters.c index 3f227ee..b38e04a 100644 --- a/src/hardwareRegisters.c +++ b/src/hardwareRegisters.c @@ -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; diff --git a/src/hardwareRegisters.h b/src/hardwareRegisters.h index b2ed142..bc3e576 100644 --- a/src/hardwareRegisters.h +++ b/src/hardwareRegisters.h @@ -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[]; diff --git a/src/hardwareRegistersTiming.c.h b/src/hardwareRegistersTiming.c.h index 45d90c2..633e9b0 100644 --- a/src/hardwareRegistersTiming.c.h +++ b/src/hardwareRegistersTiming.c.h @@ -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){ diff --git a/src/m68328.c b/src/m68328.c index 25f2c05..cd312e5 100755 --- a/src/m68328.c +++ b/src/m68328.c @@ -185,10 +185,6 @@ void m68328Execute(){ m68k_execute(cpuCycles); addSysclks(sysclks); - //abort if PLL disabled - if(palmSysclksPerClk32 < 1.0) - break; - cyclesRemaining -= sysclks; }