diff --git a/qtBuildSystem/qt-common/boolean.h b/qtBuildSystem/qt-common/boolean.h new file mode 100644 index 0000000..8a5482c --- /dev/null +++ b/qtBuildSystem/qt-common/boolean.h @@ -0,0 +1,39 @@ +/* Copyright (C) 2010-2017 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this file (boolean.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __LIBRETRO_SDK_BOOLEAN_H +#define __LIBRETRO_SDK_BOOLEAN_H + +#ifndef __cplusplus + +#if defined(_MSC_VER) && _MSC_VER < 1800 && !defined(SN_TARGET_PS3) +/* Hack applied for MSVC when compiling in C89 mode as it isn't C99 compliant. */ +#define bool unsigned char +#define true 1 +#define false 0 +#else +#include +#endif + +#endif + +#endif diff --git a/src/emulator.c b/src/emulator.c index a2443c0..58775f4 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -25,15 +25,11 @@ uint8_t palmRam[RAM_SIZE]; uint8_t palmRom[ROM_SIZE]; uint8_t palmReg[REG_SIZE]; -uint32_t palmCrystalCycles;//how many cycles before toggling the 32.768 kHz crystal -uint32_t palmCycleCounter;//can be greater then 0 if too many cycles where run - +input_t palmIo; uint16_t palmFramebuffer[160 * (160 + 60)];//really 160*160, the extra pixels are the silkscreened digitizer area -uint16_t palmButtonState; -uint16_t palmTouchscreenX; -uint16_t palmTouchscreenY; -bool palmTouchscreenTouched; -uint32_t palmClockMultiplier;//used by the emulator to overclock the emulated palm +double palmCrystalCycles;//how many cycles before toggling the 32.768 kHz crystal +double palmCycleCounter;//can be greater then 0 if too many cycles where run +double palmClockMultiplier;//used by the emulator to overclock the emulated palm void emulatorInit(uint8_t* palmRomDump){ @@ -44,13 +40,14 @@ void emulatorInit(uint8_t* palmRomDump){ memset(palmRam, 0x00, RAM_SIZE); memcpy(palmRom, palmRomDump, ROM_SIZE); memcpy(palmRam, palmRom, 256);//copy ROM header + memset(&palmIo, 0x00, sizeof(input_t)); memcpy(&palmFramebuffer[160 * 160], silkscreenData, SILKSCREEN_WIDTH * SILKSCREEN_HEIGHT * (SILKSCREEN_BPP / 8)); resetHwRegisters(); sed1376Reset(); - palmCrystalCycles = 2 * (14 * (71/*p*/ + 1) + 3/*q*/ + 1) / 2/*prescaler1*/; - palmCycleCounter = 0; + palmCrystalCycles = 2.0 * (14.0 * (71.0/*p*/ + 1.0) + 3.0/*q*/ + 1.0) / 2.0/*prescaler1*/; + palmCycleCounter = 0.0; - palmClockMultiplier = 1;//Overclock disabled + palmClockMultiplier = 1.0;//Overclock disabled lowPowerStopActive = false; m68k_set_reset_instr_callback(emulatorReset); @@ -81,12 +78,12 @@ void emulatorSaveState(uint8_t* data){ offset += RAM_SIZE; memcpy(data + offset, palmReg, REG_SIZE); offset += REG_SIZE; - memcpy(data + offset, &palmCrystalCycles, sizeof(uint32_t)); - offset += sizeof(uint32_t); - memcpy(data + offset, &palmCycleCounter, sizeof(uint32_t)); - offset += sizeof(uint32_t); + memcpy(data + offset, &palmCrystalCycles, sizeof(double)); + offset += sizeof(double); + memcpy(data + offset, &palmCycleCounter, sizeof(double)); + offset += sizeof(double); memcpy(data + offset, &clk32Counter, sizeof(uint32_t)); - offset += sizeof(uint32_t); + offset += sizeof(double); data[offset] = lowPowerStopActive; offset += 1; } @@ -99,12 +96,12 @@ void emulatorLoadState(uint8_t* data){ offset += RAM_SIZE; memcpy(palmReg, data + offset, REG_SIZE); offset += REG_SIZE; - memcpy(&palmCrystalCycles, data + offset, sizeof(uint32_t)); - offset += sizeof(uint32_t); - memcpy(&palmCycleCounter, data + offset, sizeof(uint32_t)); - offset += sizeof(uint32_t); - memcpy(&clk32Counter, data + offset, sizeof(uint32_t)); - offset += sizeof(uint32_t); + memcpy(&palmCrystalCycles, data + offset, sizeof(double)); + offset += sizeof(double); + memcpy(&palmCycleCounter, data + offset, sizeof(double)); + offset += sizeof(double); + memcpy(&clk32Counter, data + offset, sizeof(double)); + offset += sizeof(double); lowPowerStopActive = data[offset]; offset += 1; } @@ -123,5 +120,5 @@ void emulateFrame(){ } palmCycleCounter -= CPU_FREQUENCY / EMU_FPS; - printf("Ran frame, executed %d cycles.\n", palmCycleCounter + CPU_FREQUENCY / EMU_FPS); + printf("Ran frame, executed %f cycles.\n", palmCycleCounter + CPU_FREQUENCY / EMU_FPS); } diff --git a/src/emulator.h b/src/emulator.h index f40d734..3224e8a 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -11,13 +11,21 @@ enum emu_error_t{ EMU_ERROR_NOT_DOCUMENTED }; +//types +typedef struct{ + uint16_t buttonState; + uint16_t touchscreenX; + uint16_t touchscreenY; + bool touchscreenTouched; +}input_t; + //buttons #define buttonUp 0 //etc... //config options -#define EMU_FPS 60 -#define CRYSTAL_FREQUENCY 32768 +#define EMU_FPS 60.0 +#define CRYSTAL_FREQUENCY 32768.0 #define CPU_FREQUENCY (palmCrystalCycles * CRYSTAL_FREQUENCY) //memory chip addresses @@ -38,17 +46,11 @@ enum emu_error_t{ extern uint8_t palmRam[]; extern uint8_t palmRom[]; extern uint8_t palmReg[]; -extern uint32_t palmCrystalCycles; -extern uint32_t palmCycleCounter; -extern uint32_t palmRtcFrameCounter; - -//i/o +extern input_t palmIo; extern uint16_t palmFramebuffer[]; -extern uint16_t palmButtonState; -extern uint16_t palmTouchscreenX; -extern uint16_t palmTouchscreenY; -extern bool palmTouchscreenTouched; -extern uint32_t palmClockMultiplier; +extern double palmCrystalCycles; +extern double palmCycleCounter; +extern double palmClockMultiplier; //functions void emulatorInit(uint8_t* palmRomDump); diff --git a/src/hardwareregisters.c b/src/hardwareregisters.c index f111bca..836d4c9 100644 --- a/src/hardwareregisters.c +++ b/src/hardwareregisters.c @@ -11,28 +11,28 @@ #include "m68k/m68kcpu.h" -static inline unsigned int registerArrayRead8(unsigned int address){ +static inline uint8_t registerArrayRead8(uint32_t address){ return palmReg[address]; } -static inline unsigned int registerArrayRead16(unsigned int address){ +static inline uint16_t registerArrayRead16(uint32_t address){ return palmReg[address] << 8 | palmReg[address + 1]; } -static inline unsigned int registerArrayRead32(unsigned int address){ +static inline uint32_t registerArrayRead32(uint32_t address){ return palmReg[address] << 24 | palmReg[address + 1] << 16 | palmReg[address + 2] << 8 | palmReg[address + 3]; } -static inline void registerArrayWrite8(unsigned int address, unsigned int value){ +static inline void registerArrayWrite8(uint32_t address, uint8_t value){ palmReg[address] = value; } -static inline void registerArrayWrite16(unsigned int address, unsigned int value){ +static inline void registerArrayWrite16(uint32_t address, uint16_t value){ palmReg[address] = value >> 8; palmReg[address + 1] = value & 0xFF; } -static inline void registerArrayWrite32(unsigned int address, unsigned int value){ +static inline void registerArrayWrite32(uint32_t address, uint32_t value){ palmReg[address] = value >> 24; palmReg[address + 1] = (value >> 16) & 0xFF; palmReg[address + 2] = (value >> 8) & 0xFF; @@ -40,11 +40,19 @@ static inline void registerArrayWrite32(unsigned int address, unsigned int value } -uint32_t clk32Counter; +static inline void setIprIsrBit(uint32_t interruptBit){ + //allows for setting an interrupt with masking by IMR and logging in IPR + registerArrayWrite32(IPR, registerArrayRead32(IPR) | interruptBit); + registerArrayWrite32(ISR, registerArrayRead32(ISR) | (interruptBit & ~registerArrayRead32(IMR))); +} -void checkInterrupts(); -void setIprIsrBit(uint32_t interruptBit); -void clearIprIsrBit(uint32_t interruptBit); +static inline void clearIprIsrBit(uint32_t interruptBit){ + registerArrayWrite32(IPR, registerArrayRead32(IPR) & ~interruptBit); + registerArrayWrite32(ISR, registerArrayRead32(ISR) & ~interruptBit); +} + + +uint32_t clk32Counter; void printUnknownHwAccess(unsigned int address, unsigned int value, unsigned int size, bool isWrite){ @@ -56,29 +64,29 @@ void printUnknownHwAccess(unsigned int address, unsigned int value, unsigned int } } -void setPllfsr16(unsigned int value){ +static inline void setPllfsr16(uint16_t value){ if(!(registerArrayRead16(PLLFSR) & 0x4000)){ //frequency protect bit not set registerArrayWrite16(PLLFSR, value & 0x4FFF); - uint32_t prescaler1 = (registerArrayRead16(PLLCR) & 0x0080) ? 2 : 1; - uint32_t p = value & 0x00FF; - uint32_t q = (value & 0x0F00) >> 8; - palmCrystalCycles = 2 * (14 * (p + 1) + q + 1) / prescaler1; - printf("New CPU frequency of:%d cycles per second.\n", CPU_FREQUENCY); - printf("New clk32 cycle count of :%d.\n", palmCrystalCycles); + double prescaler1 = (registerArrayRead16(PLLCR) & 0x0080) ? 2 : 1; + double p = value & 0x00FF; + double q = (value & 0x0F00) >> 8; + palmCrystalCycles = 2.0 * (14.0 * (p + 1.0) + q + 1.0) / prescaler1; + printf("New CPU frequency of:%f cycles per second.\n", CPU_FREQUENCY); + printf("New clk32 cycle count of :%f.\n", palmCrystalCycles); } } -void setPllcr(unsigned int value){ +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); - uint32_t prescaler1 = (value & 0x0080) ? 2 : 1; - uint32_t p = pllfsr & 0x00FF; - uint32_t q = (pllfsr & 0x0F00) >> 8; - palmCrystalCycles = 2 * (14 * (p + 1) + q + 1) / prescaler1; - printf("New CPU frequency of:%d cycles per second.\n", CPU_FREQUENCY); - printf("New clk32 cycle count of :%d.\n", palmCrystalCycles); + double prescaler1 = (value & 0x0080) ? 2 : 1; + double p = pllfsr & 0x00FF; + double q = (pllfsr & 0x0F00) >> 8; + palmCrystalCycles = 2.0 * (14.0 * (p + 1.0) + q + 1.0) / prescaler1; + printf("New CPU frequency of:%f cycles per second.\n", CPU_FREQUENCY); + printf("New clk32 cycle count of :%f.\n", palmCrystalCycles); if(value & 0x0008){ //the pll is disabled, the cpu is off, end execution now @@ -86,39 +94,81 @@ void setPllcr(unsigned int value){ } } +static inline double sysclksPerClk32(){ + //extreme precision must be used with the prescalers since it is possible to divide the int so much it is zero and timers will never increment + uint16_t pllcr = registerArrayRead16(PLLCR); + double sysclks = palmCrystalCycles; + uint16_t sysclkSelect = (pllcr >> 8) & 0x0003; + + if(pllcr & 0x0080){ + //prescaler 1 enabled, divide by 2 + sysclks /= 2.0; + } + + if(pllcr & 0x0020){ + //prescaler 2 enabled, divides value from prescaler 1 by 2 + sysclks /= 2.0; + } + + switch(sysclkSelect){ + + case 0x0000: + sysclks /= 2.0; + break; + + case 0x0001: + sysclks /= 4.0; + break; + + case 0x0002: + sysclks /= 8.0; + break; + + case 0x0003: + sysclks /= 16.0; + break; + + default: + //no divide for 0x0004, 0x0005, 0x0006 or 0x0007 + break; + } + + return sysclks; +} + static inline void rtiInterruptClk32(){ //this function is part of clk32(); uint16_t triggeredRtiInterrupts = 0; - if(clk32Counter % (CRYSTAL_FREQUENCY / 512) == 0){ + if(clk32Counter % ((uint32_t)CRYSTAL_FREQUENCY / 512) == 0){ //RIS7 - 512HZ triggeredRtiInterrupts |= 0x8000; } - if(clk32Counter % (CRYSTAL_FREQUENCY / 256) == 0){ + if(clk32Counter % ((uint32_t)CRYSTAL_FREQUENCY / 256) == 0){ //RIS6 - 256HZ triggeredRtiInterrupts |= 0x4000; } - if(clk32Counter % (CRYSTAL_FREQUENCY / 128) == 0){ + if(clk32Counter % ((uint32_t)CRYSTAL_FREQUENCY / 128) == 0){ //RIS5 - 128HZ triggeredRtiInterrupts |= 0x2000; } - if(clk32Counter % (CRYSTAL_FREQUENCY / 64) == 0){ + if(clk32Counter % ((uint32_t)CRYSTAL_FREQUENCY / 64) == 0){ //RIS4 - 64HZ triggeredRtiInterrupts |= 0x1000; } - if(clk32Counter % (CRYSTAL_FREQUENCY / 32) == 0){ + if(clk32Counter % ((uint32_t)CRYSTAL_FREQUENCY / 32) == 0){ //RIS3 - 32HZ triggeredRtiInterrupts |= 0x0800; } - if(clk32Counter % (CRYSTAL_FREQUENCY / 16) == 0){ + if(clk32Counter % ((uint32_t)CRYSTAL_FREQUENCY / 16) == 0){ //RIS2 - 16HZ triggeredRtiInterrupts |= 0x0400; } - if(clk32Counter % (CRYSTAL_FREQUENCY / 8) == 0){ + if(clk32Counter % ((uint32_t)CRYSTAL_FREQUENCY / 8) == 0){ //RIS1 - 8HZ triggeredRtiInterrupts |= 0x0200; } - if(clk32Counter % (CRYSTAL_FREQUENCY / 4) == 0){ + if(clk32Counter % ((uint32_t)CRYSTAL_FREQUENCY / 4) == 0){ //RIS0 - 4HZ triggeredRtiInterrupts |= 0x0100; } @@ -130,15 +180,15 @@ static inline void rtiInterruptClk32(){ } } -void setIprIsrBit(uint32_t interruptBit){ - //allows for setting an interrupt with masking by IMR and logging in IPR - registerArrayWrite32(IPR, registerArrayRead32(IPR) | interruptBit); - registerArrayWrite32(ISR, registerArrayRead32(ISR) | (interruptBit & ~registerArrayRead32(IMR))); -} - -void clearIprIsrBit(uint32_t interruptBit){ - registerArrayWrite32(IPR, registerArrayRead32(IPR) & ~interruptBit); - registerArrayWrite32(ISR, registerArrayRead32(ISR) & ~interruptBit); +static inline void timer12Clk32(){ + //this function is part of clk32(); + uint16_t timer1Control = registerArrayRead16(TCTL1); + uint16_t timer2Control = registerArrayRead16(TCTL2); + + if(timer1Control & 0x0001 && timer1Control & 0x000E){ + //enabled and clock source set + + } } void checkInterrupts(){ @@ -299,7 +349,7 @@ void checkInterrupts(){ } -void rtcAddSecond(){ +static inline void rtcAddSecondClk32(){ //this function is part of clk32(); //rtc @@ -350,7 +400,7 @@ void rtcAddSecond(){ //watchdog enabled watchdogState += 0x0100;//add second to watchdog timer watchdogState &= 0x0383;//cap overflow - if(watchdogState & 0x0200 == 0x0200){ + if((watchdogState & 0x0200) == 0x0200){ //time expired if(watchdogState & 0x0002){ //interrupt @@ -371,15 +421,14 @@ void clk32(){ //rolls over every second if(clk32Counter >= CRYSTAL_FREQUENCY - 1){ clk32Counter = 0; - rtcAddSecond(); + rtcAddSecondClk32(); } else{ clk32Counter++; } rtiInterruptClk32(); - - //more will be added here for timers + timer12Clk32(); checkInterrupts(); } diff --git a/tests/HwRegTest11.txt b/tests/HwRegTest11.txt new file mode 100644 index 0000000..9d5d262 --- /dev/null +++ b/tests/HwRegTest11.txt @@ -0,0 +1,244 @@ +double accuracy test 32768 == 32768. +New CPU frequency of:33161216.000000 cycles per second. +New clk32 cycle count of :1012.000000. +Cpu Wrote 8 bits of 0x00000020 to register 0x0409. +Cpu Wrote 8 bits of 0x00000060 to register 0x0408. +Cpu Wrote 8 bits of 0x00000000 to register 0x0410. +Cpu Wrote 8 bits of 0x00000000 to register 0x0411. +Cpu Wrote 8 bits of 0x0000000F to register 0x041C. +Cpu Wrote 8 bits of 0x000000F0 to register 0x0419. +Cpu Wrote 8 bits of 0x00000000 to register 0x0418. +Cpu Wrote 8 bits of 0x0000000F to register 0x041D. +Cpu Wrote 8 bits of 0x0000000F to register 0x041F. +Cpu Wrote 8 bits of 0x0000000F to register 0x0419. +Cpu Wrote 8 bits of 0x0000000F to register 0x041E. +Cpu Wrote 8 bits of 0x00000008 to register 0x0421. +Cpu Wrote 8 bits of 0x00000088 to register 0x0420. +Cpu Wrote 8 bits of 0x00000002 to register 0x0429. +Cpu Wrote 8 bits of 0x00000020 to register 0x0428. +Cpu Wrote 8 bits of 0x0000002C to register 0x0430. +Cpu Wrote 8 bits of 0x00000004 to register 0x0431. +Cpu Wrote 8 bits of 0x00000000 to register 0x0439. +Cpu Wrote 8 bits of 0x0000000F to register 0x0438. +Cpu Wrote 8 bits of 0x00000008 to register 0x0441. +Cpu Wrote 8 bits of 0x000000F9 to register 0x0440. +Cpu Wrote 8 bits of 0x00000020 to register 0x0448. +Cpu Wrote 8 bits of 0x00000020 to register 0x0449. +Cpu Wrote 8 bits of 0x00000000 to register 0x0A27. +Cpu Wrote 16 bits of 0x00000000 to register 0x0600. +Cpu Wrote 8 bits of 0x000000F8 to register 0x0000. +Cpu Wrote 16 bits of 0x00008000 to register 0x0100. +Cpu Wrote 16 bits of 0x000001AB to register 0x0110. +Cpu Wrote 16 bits of 0x0000FFC0 to register 0x0102. +Cpu Wrote 16 bits of 0x000001F3 to register 0x0112. +Cpu Wrote 16 bits of 0x00008200 to register 0x0104. +Cpu Wrote 16 bits of 0x00000101 to register 0x0114. +Cpu Wrote 16 bits of 0x00000000 to register 0x0106. +Cpu Wrote 16 bits of 0x00001E83 to register 0x0116. +Cpu Wrote 16 bits of 0x00000040 to register 0x010A. +Cpu Wrote 16 bits of 0x00000000 to register 0x0C02. +Cpu Wrote 16 bits of 0x00004020 to register 0x0C00. +Cpu Wrote 16 bits of 0x00008000 to register 0x0C02. +Cpu Wrote 16 bits of 0x00001A81 to register 0x0116. +Cpu Wrote 16 bits of 0x00000000 to register 0x0C02. +Cpu Wrote 16 bits of 0x00008000 to register 0x0C02. +Cpu Read 16 bits from register 0x0310. +New CPU frequency of:33161216.000000 cycles per second. +New clk32 cycle count of :1012.000000. +New CPU frequency of:33161216.000000 cycles per second. +New clk32 cycle count of :1012.000000. +Ran frame, executed 553603.000000 cycles. +Ran frame, executed 553468.066667 cycles. +Ran frame, executed 553333.133333 cycles. +Ran frame, executed 553198.200000 cycles. +Ran frame, executed 553063.266667 cycles. +Ran frame, executed 552928.333333 cycles. +Ran frame, executed 552793.400000 cycles. +Ran frame, executed 553670.466667 cycles. +Ran frame, executed 553535.533333 cycles. +Ran frame, executed 553400.600000 cycles. +Ran frame, executed 553265.666667 cycles. +Ran frame, executed 553130.733333 cycles. +Ran frame, executed 552995.800000 cycles. +Ran frame, executed 552860.866667 cycles. +Ran frame, executed 552725.933333 cycles. +Ran frame, executed 553603.000000 cycles. +Ran frame, executed 553468.066667 cycles. +Ran frame, executed 553333.133333 cycles. +Ran frame, executed 553198.200000 cycles. +Ran frame, executed 553063.266667 cycles. +Ran frame, executed 552928.333333 cycles. +Ran frame, executed 552793.400000 cycles. +Ran frame, executed 553670.466667 cycles. +Ran frame, executed 553535.533333 cycles. +Ran frame, executed 553400.600000 cycles. +Ran frame, executed 553265.666667 cycles. +Ran frame, executed 553130.733333 cycles. +Ran frame, executed 552995.800000 cycles. +Ran frame, executed 552860.866667 cycles. +Ran frame, executed 552725.933333 cycles. +Ran frame, executed 553603.000000 cycles. +Ran frame, executed 553468.066667 cycles. +Ran frame, executed 553333.133333 cycles. +Ran frame, executed 553198.200000 cycles. +Ran frame, executed 553063.266667 cycles. +Ran frame, executed 552928.333333 cycles. +Ran frame, executed 552793.400000 cycles. +Ran frame, executed 553670.466667 cycles. +Ran frame, executed 553535.533333 cycles. +Ran frame, executed 553400.600000 cycles. +Ran frame, executed 553265.666667 cycles. +Ran frame, executed 553130.733333 cycles. +Ran frame, executed 552995.800000 cycles. +Ran frame, executed 552860.866667 cycles. +Ran frame, executed 552725.933333 cycles. +Ran frame, executed 553603.000000 cycles. +Ran frame, executed 553468.066667 cycles. +Ran frame, executed 553333.133333 cycles. +Ran frame, executed 553198.200000 cycles. +Ran frame, executed 553063.266667 cycles. +Ran frame, executed 552928.333333 cycles. +Ran frame, executed 552793.400000 cycles. +Ran frame, executed 553670.466667 cycles. +Ran frame, executed 553535.533333 cycles. +Ran frame, executed 553400.600000 cycles. +Ran frame, executed 553265.666667 cycles. +Ran frame, executed 553130.733333 cycles. +Ran frame, executed 552995.800000 cycles. +Ran frame, executed 552860.866667 cycles. +Ran frame, executed 552725.933333 cycles. +Ran frame, executed 553603.000000 cycles. +Ran frame, executed 553468.066667 cycles. +Ran frame, executed 553333.133333 cycles. +Ran frame, executed 553198.200000 cycles. +Ran frame, executed 553063.266667 cycles. +Ran frame, executed 552928.333333 cycles. +Ran frame, executed 552793.400000 cycles. +Ran frame, executed 553670.466667 cycles. +Ran frame, executed 553535.533333 cycles. +Ran frame, executed 553400.600000 cycles. +Ran frame, executed 553265.666667 cycles. +Ran frame, executed 553130.733333 cycles. +Ran frame, executed 552995.800000 cycles. +Ran frame, executed 552860.866667 cycles. +Ran frame, executed 552725.933333 cycles. +Ran frame, executed 553603.000000 cycles. +Ran frame, executed 553468.066667 cycles. +Ran frame, executed 553333.133333 cycles. +Ran frame, executed 553198.200000 cycles. +Ran frame, executed 553063.266667 cycles. +Ran frame, executed 552928.333333 cycles. +Ran frame, executed 552793.400000 cycles. +Ran frame, executed 553670.466667 cycles. +Ran frame, executed 553535.533333 cycles. +Ran frame, executed 553400.600000 cycles. +Ran frame, executed 553265.666667 cycles. +Ran frame, executed 553130.733333 cycles. +Ran frame, executed 552995.800000 cycles. +Ran frame, executed 552860.866667 cycles. +Ran frame, executed 552725.933333 cycles. +Ran frame, executed 553603.000000 cycles. +Ran frame, executed 553468.066667 cycles. +Ran frame, executed 553333.133333 cycles. +Ran frame, executed 553198.200000 cycles. +Ran frame, executed 553063.266667 cycles. +Ran frame, executed 552928.333333 cycles. +Ran frame, executed 552793.400000 cycles. +Ran frame, executed 553670.466667 cycles. +Ran frame, executed 553535.533333 cycles. +Ran frame, executed 553400.600000 cycles. +Ran frame, executed 553265.666667 cycles. +Ran frame, executed 553130.733333 cycles. +Ran frame, executed 552995.800000 cycles. +Ran frame, executed 552860.866667 cycles. +Ran frame, executed 552725.933333 cycles. +Ran frame, executed 553603.000000 cycles. +Ran frame, executed 553468.066667 cycles. +Ran frame, executed 553333.133333 cycles. +Ran frame, executed 553198.200000 cycles. +Ran frame, executed 553063.266667 cycles. +Ran frame, executed 552928.333333 cycles. +Ran frame, executed 552793.400000 cycles. +Ran frame, executed 553670.466667 cycles. +Ran frame, executed 553535.533333 cycles. +Ran frame, executed 553400.600000 cycles. +Ran frame, executed 553265.666667 cycles. +Ran frame, executed 553130.733333 cycles. +Ran frame, executed 552995.800000 cycles. +Ran frame, executed 552860.866667 cycles. +Ran frame, executed 552725.933333 cycles. +Ran frame, executed 553603.000000 cycles. +Ran frame, executed 553468.066667 cycles. +Ran frame, executed 553333.133333 cycles. +Ran frame, executed 553198.200000 cycles. +Ran frame, executed 553063.266667 cycles. +Ran frame, executed 552928.333333 cycles. +Ran frame, executed 552793.400000 cycles. +Ran frame, executed 553670.466667 cycles. +Ran frame, executed 553535.533333 cycles. +Ran frame, executed 553400.600000 cycles. +Ran frame, executed 553265.666667 cycles. +Ran frame, executed 553130.733333 cycles. +Ran frame, executed 552995.800000 cycles. +Ran frame, executed 552860.866667 cycles. +Ran frame, executed 552725.933333 cycles. +Ran frame, executed 553603.000000 cycles. +Ran frame, executed 553468.066667 cycles. +Ran frame, executed 553333.133333 cycles. +Ran frame, executed 553198.200000 cycles. +Ran frame, executed 553063.266667 cycles. +Ran frame, executed 552928.333333 cycles. +Ran frame, executed 552793.400000 cycles. +Ran frame, executed 553670.466667 cycles. +Ran frame, executed 553535.533333 cycles. +Ran frame, executed 553400.600000 cycles. +Ran frame, executed 553265.666667 cycles. +Ran frame, executed 553130.733333 cycles. +Ran frame, executed 552995.800000 cycles. +Ran frame, executed 552860.866667 cycles. +Ran frame, executed 552725.933333 cycles. +Ran frame, executed 553603.000000 cycles. +Ran frame, executed 553468.066667 cycles. +Ran frame, executed 553333.133333 cycles. +Ran frame, executed 553198.200000 cycles. +Ran frame, executed 553063.266667 cycles. +Ran frame, executed 552928.333333 cycles. +Ran frame, executed 552793.400000 cycles. +Ran frame, executed 553670.466667 cycles. +Ran frame, executed 553535.533333 cycles. +Ran frame, executed 553400.600000 cycles. +Ran frame, executed 553265.666667 cycles. +Ran frame, executed 553130.733333 cycles. +Ran frame, executed 552995.800000 cycles. +Ran frame, executed 552860.866667 cycles. +Ran frame, executed 552725.933333 cycles. +Ran frame, executed 553603.000000 cycles. +Ran frame, executed 553468.066667 cycles. +Ran frame, executed 553333.133333 cycles. +Ran frame, executed 553198.200000 cycles. +Ran frame, executed 553063.266667 cycles. +Ran frame, executed 552928.333333 cycles. +Ran frame, executed 552793.400000 cycles. +Ran frame, executed 553670.466667 cycles. +Ran frame, executed 553535.533333 cycles. +Ran frame, executed 553400.600000 cycles. +Ran frame, executed 553265.666667 cycles. +Ran frame, executed 553130.733333 cycles. +Ran frame, executed 552995.800000 cycles. +Ran frame, executed 552860.866667 cycles. +Ran frame, executed 552725.933333 cycles. +Ran frame, executed 553603.000000 cycles. +Ran frame, executed 553468.066667 cycles. +Ran frame, executed 553333.133333 cycles. +Ran frame, executed 553198.200000 cycles. +Ran frame, executed 553063.266667 cycles. +Ran frame, executed 552928.333333 cycles. +Ran frame, executed 552793.400000 cycles. +Ran frame, executed 553670.466667 cycles. +Ran frame, executed 553535.533333 cycles. +Ran frame, executed 553400.600000 cycles. +Ran frame, executed 553265.666667 cycles. +Ran frame, executed 553130.733333 cycles. +Ran frame, executed 552995.800000 cycles. +Ran frame, executed 552860.866667 cycles. +Ran frame, executed 552725.933333 cycles.