mirror of
https://github.com/libretro/Mu.git
synced 2026-09-23 15:15:43 +00:00
Add PCTRL register, use specific function to set CPU speed
This commit is contained in:
@@ -23,7 +23,8 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
||||
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
CONFIG(debug, debug|release){
|
||||
DEFINES += FRONTEND_DEBUG EMU_DEBUG EMU_OPCODE_LEVEL_DEBUG EMU_LOG_REGISTER_ACCESS_UNKNOWN EMU_LOG_APIS
|
||||
DEFINES += FRONTEND_DEBUG EMU_DEBUG EMU_OPCODE_LEVEL_DEBUG EMU_LOG_REGISTER_ACCESS_UNKNOWN
|
||||
# EMU_LOG_APIS
|
||||
}
|
||||
|
||||
INCLUDEPATH += $$PWD/qt-common/include
|
||||
|
||||
@@ -187,7 +187,6 @@ void emulatorInit(uint8_t* palmRomDump, uint8_t* palmBootDump, uint32_t specialF
|
||||
#endif
|
||||
resetHwRegisters();
|
||||
lowPowerStopActive = false;
|
||||
palmCrystalCycles = 2.0 * (14.0 * (71.0/*p*/ + 1.0) + 3.0/*q*/ + 1.0) / 2.0/*prescaler1*/;
|
||||
palmCycleCounter = 0.0;
|
||||
|
||||
//memory
|
||||
|
||||
@@ -19,8 +19,9 @@ double timer2CycleCounter;
|
||||
|
||||
|
||||
bool pllIsOn();
|
||||
void checkInterrupts();
|
||||
void checkPortDInterrupts();
|
||||
static void checkInterrupts();
|
||||
static void checkPortDInterrupts();
|
||||
static void recalculateCpuSpeed();
|
||||
|
||||
#include "hardwareRegistersAccessors.c.h"
|
||||
#include "hardwareRegistersTiming.c.h"
|
||||
@@ -53,6 +54,8 @@ int interruptAcknowledge(int intLevel){
|
||||
vector = vectorOffset | intLevel;
|
||||
|
||||
lowPowerStopActive = false;
|
||||
registerArrayWrite8(PCTLR, registerArrayRead8(PCTLR) & 0x1F);
|
||||
recalculateCpuSpeed();
|
||||
|
||||
//the interrupt should only be cleared after its been handled
|
||||
|
||||
@@ -86,6 +89,22 @@ void setPrivilegeViolation(){
|
||||
registerArrayWrite8(SCR, scr | 0x20);
|
||||
}
|
||||
|
||||
static void recalculateCpuSpeed(){
|
||||
uint16_t pllfsr = registerArrayRead16(PLLFSR);
|
||||
uint8_t pctlr = registerArrayRead8(PCTLR);
|
||||
double prescaler1 = (registerArrayRead16(PLLCR) & 0x0080) ? 2.0 : 1.0;
|
||||
double p = pllfsr & 0x00FF;
|
||||
double q = (pllfsr & 0x0F00) >> 8;
|
||||
double newCpuSpeed = 2.0 * (14.0 * (p + 1.0) + q + 1.0) / prescaler1;
|
||||
|
||||
if(pctlr & 0x80)
|
||||
newCpuSpeed *= (double)(pctlr & 0x1F) / 31.0;
|
||||
|
||||
debugLog("New CPU frequency of:%f cycles per second.\n", newCpuSpeed * CRYSTAL_FREQUENCY);
|
||||
debugLog("New CLK32 cycle count of:%f.\n", newCpuSpeed);
|
||||
palmCrystalCycles = newCpuSpeed;
|
||||
}
|
||||
|
||||
static inline void pllWakeCpuIfOff(){
|
||||
uint16_t pllcr = registerArrayRead16(PLLCR);
|
||||
if(!pllIsOn() && pllWakeWait == -1){
|
||||
@@ -111,7 +130,7 @@ static inline void pllWakeCpuIfOff(){
|
||||
}
|
||||
}
|
||||
|
||||
void checkInterrupts(){
|
||||
static void checkInterrupts(){
|
||||
uint32_t activeInterrupts = registerArrayRead32(ISR);
|
||||
uint16_t interruptLevelControlRegister = registerArrayRead16(ILCR);
|
||||
uint16_t portDEdgeSelect = registerArrayRead16(PDIRQEG);
|
||||
@@ -229,7 +248,7 @@ void checkInterrupts(){
|
||||
m68k_set_irq(intLevel);//should be called even if intLevel is 0, that is how the interrupt state gets cleared
|
||||
}
|
||||
|
||||
void checkPortDInterrupts(){
|
||||
static void checkPortDInterrupts(){
|
||||
uint8_t portDValue = getPortDValue();
|
||||
uint8_t portDDir = registerArrayRead8(PDDIR);
|
||||
uint8_t portDIntEnable = registerArrayRead8(PDIRQEN);
|
||||
@@ -489,6 +508,11 @@ void setHwRegister8(unsigned int address, unsigned int value){
|
||||
case SCR:
|
||||
setScr(value);
|
||||
break;
|
||||
|
||||
case PCTLR:
|
||||
registerArrayWrite8(address, value & 0x9F);
|
||||
recalculateCpuSpeed();
|
||||
break;
|
||||
|
||||
case IVR:
|
||||
//write without the bottom 3 bits
|
||||
@@ -658,11 +682,19 @@ void setHwRegister16(unsigned int address, unsigned int value){
|
||||
break;
|
||||
|
||||
case PLLFSR:
|
||||
setPllfsr16(value);
|
||||
setPllfsr(value);
|
||||
break;
|
||||
|
||||
case PLLCR:
|
||||
setPllcr(value);
|
||||
//values that matter are disable PLL, prescaler 1 and wakeselect
|
||||
registerArrayWrite16(PLLCR, value & 0x3FBB);
|
||||
recalculateCpuSpeed();
|
||||
|
||||
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");
|
||||
}
|
||||
break;
|
||||
|
||||
case ICR:
|
||||
@@ -937,6 +969,8 @@ void resetHwRegisters(){
|
||||
//add register settings to misc I/O
|
||||
updateAlarmLedStatus();
|
||||
updateVibratorStatus();
|
||||
|
||||
recalculateCpuSpeed();
|
||||
}
|
||||
|
||||
void setRtc(uint32_t days, uint32_t hours, uint32_t minutes, uint32_t seconds){
|
||||
|
||||
@@ -150,35 +150,12 @@ static inline void setCsctrl1(uint16_t value){
|
||||
|
||||
//csctrl 2 and 3 only deal with timing and bus transfer size
|
||||
|
||||
static inline void setPllfsr16(uint16_t value){
|
||||
static inline void setPllfsr(uint16_t value){
|
||||
uint16_t oldPllfsr = registerArrayRead16(PLLFSR);
|
||||
if(!(oldPllfsr & 0x4000)){
|
||||
//frequency protect bit not set
|
||||
registerArrayWrite16(PLLFSR, (value & 0x4FFF) | (oldPllfsr & 0x8000));//preserve CLK32 bit
|
||||
double prescaler1 = (registerArrayRead16(PLLCR) & 0x0080) ? 2.0 : 1.0;
|
||||
double p = value & 0x00FF;
|
||||
double q = (value & 0x0F00) >> 8;
|
||||
palmCrystalCycles = 2.0 * (14.0 * (p + 1.0) + q + 1.0) / prescaler1;
|
||||
debugLog("New CPU frequency of:%f cycles per second.\n", CPU_FREQUENCY);
|
||||
debugLog("New CLK32 cycle count of:%f.\n", palmCrystalCycles);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void setPllcr(uint16_t value){
|
||||
//values that matter are disable PLL, prescaler 1 and possibly wakeselect
|
||||
registerArrayWrite16(PLLCR, value & 0x3FBB);
|
||||
uint16_t pllfsr = registerArrayRead16(PLLFSR);
|
||||
double prescaler1 = (value & 0x0080) ? 2.0 : 1.0;
|
||||
double p = pllfsr & 0x00FF;
|
||||
double q = (pllfsr & 0x0F00) >> 8;
|
||||
palmCrystalCycles = 2.0 * (14.0 * (p + 1.0) + q + 1.0) / prescaler1;
|
||||
debugLog("New CPU frequency of:%f cycles per second.\n", CPU_FREQUENCY);
|
||||
debugLog("New CLK32 cycle count of:%f.\n", palmCrystalCycles);
|
||||
|
||||
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");
|
||||
recalculateCpuSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -296,8 +296,8 @@ void sed1376Render(){
|
||||
for(uint16_t pixelX = 0; pixelX < 160; pixelX++)
|
||||
palmFramebuffer[pixelY * 160 + pixelX] = renderPixel(pixelX, pixelY);
|
||||
|
||||
//debugLog("Screen start address:0x%08X, buffer width:%d, swivel view:%d degrees\n", screenStartAddress, lineSize, rotation);
|
||||
//debugLog("Screen format, color:%s, BPP:%d\n", color ? "true" : "false", bitDepth);
|
||||
debugLog("Screen start address:0x%08X, buffer width:%d, swivel view:%d degrees\n", screenStartAddress, lineSize, rotation);
|
||||
debugLog("Screen format, color:%s, BPP:%d\n", color ? "true" : "false", bitDepth);
|
||||
|
||||
if(pictureInPictureEnabled){
|
||||
uint16_t pipStartX = sed1376Registers[PIP_X_START_1] << 8 | sed1376Registers[PIP_X_START_0];
|
||||
@@ -312,7 +312,7 @@ void sed1376Render(){
|
||||
pipStartY *= 32 / bitDepth;
|
||||
pipEndY *= 32 / bitDepth;
|
||||
}
|
||||
//debugLog("PIP state, start x:%d, end x:%d, start y:%d, end y:%d\n", pipStartX, pipEndX, pipStartY, pipEndY);
|
||||
debugLog("PIP state, start x:%d, end x:%d, start y:%d, end y:%d\n", pipStartX, pipEndX, pipStartY, pipEndY);
|
||||
if(pipStartX < 160 && pipStartY < 160){
|
||||
pipEndX = pipEndX < 160 ? pipEndX : 160;
|
||||
pipEndY = pipEndY < 160 ? pipEndY : 160;
|
||||
|
||||
@@ -33,6 +33,7 @@ byte and word swap bits
|
||||
|
||||
|
||||
Fixed:
|
||||
PCTLR, can divide CPU speed by 1<->31
|
||||
Palm OS usage of the "rte" instruction is incompatible with the 68020, switch to 68000 core
|
||||
System Control Register, 0xXXFFF000 all upper banks are registers mode
|
||||
Port D keyboard enable register
|
||||
|
||||
Reference in New Issue
Block a user