diff --git a/src/dbvzRegisterAccessors.c.h b/src/dbvzRegisterAccessors.c.h index 9ea86d3..a8bacab 100644 --- a/src/dbvzRegisterAccessors.c.h +++ b/src/dbvzRegisterAccessors.c.h @@ -191,7 +191,7 @@ int32_t pwm1FifoRunSample(int32_t now, int32_t clockOffset){ for(index = 0; index < repeat; index++){ #if !defined(EMU_NO_SAFETY) - if(audioNow + audioSampleDuration >= AUDIO_CLOCK_RATE) + if(audioNow + audioSampleDuration >= DBVZ_AUDIO_MAX_CLOCK_RATE) break; #endif @@ -557,6 +557,26 @@ static void setSpiCont2(uint16_t value){ registerArrayWrite16(SPICONT2, value & 0xE3FF); } +static void updateUart1PortState(void){ + if(palmIrSetPortProperties){ + uint16_t ustcnt1 = registerArrayRead16(USTCNT1); + uint16_t ubaud1 = registerArrayRead16(UBAUD1); + uint8_t divider = 1 << (ubaud1 >> 8 & 0x07); + uint8_t prescaler = 65 - (ubaud1 & 0x001F); + bool baudSrc = !!(ubaud1 & 0x0800); + serial_port_properties_t properties; + + properties.enable = !!(ustcnt1 & 0x8000); + properties.enableParity = !!(ustcnt1 & 0x0800); + properties.oddParity = !!(ustcnt1 & 0x0400); + properties.stopBits = !!(ustcnt1 & 0x0200) ? 2 : 1; + properties.use8BitMode = !!(ustcnt1 & 0x0100); + properties.baudRate = (baudSrc ? EMU_SERIAL_USE_EXTERNAL_CLOCK_SOURCE : sysclksPerClk32() * M515_CRYSTAL_FREQUENCY) / prescaler / divider; + + palmIrSetPortProperties(&properties); + } +} + static void updateUart1Interrupt(void){ //the UART1 interrupt has a rather complex set of trigger methods so they all have to be checked after one changes to prevent clearing a valid interrupt thats on the same line uint16_t ustcnt1 = registerArrayRead16(USTCNT1); @@ -613,6 +633,12 @@ static void setUstcnt1(uint16_t value){ updateUart1Interrupt(); } +static void updateUart2PortState(void){ + if(palmSerialSetPortProperties){ + //TODO: UART2 is unemulated right now + } +} + static void updateUart2Interrupt(void){ //TODO: UART2 is unemulated right now } diff --git a/src/dbvzTiming.c.h b/src/dbvzTiming.c.h index 80168b9..0773f40 100644 --- a/src/dbvzTiming.c.h +++ b/src/dbvzTiming.c.h @@ -417,15 +417,15 @@ static void dbvzAddSysclks(double count){ } static int32_t audioGetFramePercentIncrementFromClk32s(int32_t count){ - return (double)count / ((double)M515_CRYSTAL_FREQUENCY / EMU_FPS) * AUDIO_END_OF_FRAME; + return (double)count / ((double)M515_CRYSTAL_FREQUENCY / EMU_FPS) * DBVZ_AUDIO_END_OF_FRAME; } static int32_t audioGetFramePercentIncrementFromSysclks(double count){ - return count / (dbvzSysclksPerClk32 * ((double)M515_CRYSTAL_FREQUENCY / EMU_FPS)) * AUDIO_END_OF_FRAME; + return count / (dbvzSysclksPerClk32 * ((double)M515_CRYSTAL_FREQUENCY / EMU_FPS)) * DBVZ_AUDIO_END_OF_FRAME; } static int32_t audioGetFramePercentage(void){ //returns how much of the frame has executed - //0% = 0, 100% = AUDIO_END_OF_FRAME + //0% = 0, 100% = DBVZ_AUDIO_END_OF_FRAME return audioGetFramePercentIncrementFromClk32s(dbvzFrameClk32s) + (dbvzIsPllOn() ? audioGetFramePercentIncrementFromSysclks(dbvzClk32Sysclks) : 0); } diff --git a/src/emulator.c b/src/emulator.c index ca8be5e..b89ca77 100644 --- a/src/emulator.c +++ b/src/emulator.c @@ -60,10 +60,12 @@ int16_t* palmAudio; blip_t* palmAudioResampler; 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 (*palmIrSetPortProperties)(serial_port_properties_t* properties);//configure port I/O behavior, used for proxyed native I/R connections uint32_t (*palmIrDataSize)(void);//returns the current number of bytes in the hosts IR receive FIFO uint16_t (*palmIrDataReceive)(void);//called by the emulator to read the hosts IR receive FIFO void (*palmIrDataSend)(uint16_t data);//called by the emulator to send IR data void (*palmIrDataFlush)(void);//called by the emulator to delete all data in the hosts IR receive FIFO +void (*palmSerialSetPortProperties)(serial_port_properties_t* properties);//configure port I/O behavior, used for proxyed native serial connections uint32_t (*palmSerialDataSize)(void);//returns the current number of bytes in the hosts serial receive FIFO uint16_t (*palmSerialDataReceive)(void);//called by the emulator to read the hosts serial receive FIFO void (*palmSerialDataSend)(uint16_t data);//called by the emulator to send serial data @@ -86,10 +88,12 @@ uint32_t emulatorInit(uint8_t* palmRomData, uint32_t palmRomSize, uint8_t* palmB if(!palmRomData || palmRomSize < 0x8) return EMU_ERROR_INVALID_PARAMETER; + palmIrSetPortProperties = NULL; palmIrDataSize = NULL; palmIrDataReceive = NULL; palmIrDataSend = NULL; palmIrDataFlush = NULL; + palmSerialSetPortProperties = NULL; palmSerialDataSize = NULL; palmSerialDataReceive = NULL; palmSerialDataSend = NULL; @@ -133,7 +137,7 @@ uint32_t emulatorInit(uint8_t* palmRomData, uint32_t palmRomSize, uint8_t* palmB //initialize components, I dont think theres much in a Tungsten T3 pxa260Framebuffer = palmFramebuffer; - blip_set_rates(palmAudioResampler, AUDIO_CLOCK_RATE, AUDIO_SAMPLE_RATE); + blip_set_rates(palmAudioResampler, DBVZ_AUDIO_MAX_CLOCK_RATE, AUDIO_SAMPLE_RATE); sandboxInit(); //reset everything @@ -179,7 +183,7 @@ uint32_t emulatorInit(uint8_t* palmRomData, uint32_t palmRomSize, uint8_t* palmB sed1376Framebuffer = palmFramebuffer; //initialize components - blip_set_rates(palmAudioResampler, AUDIO_CLOCK_RATE, AUDIO_SAMPLE_RATE); + blip_set_rates(palmAudioResampler, DBVZ_AUDIO_MAX_CLOCK_RATE, AUDIO_SAMPLE_RATE); sandboxInit(); //reset everything @@ -270,6 +274,15 @@ void emulatorSetRtc(uint16_t days, uint8_t hours, uint8_t minutes, uint8_t secon dbvzSetRtc(days, hours, minutes, seconds); } +void emulatorSetCpuSpeed(uint16_t percent){ +#if defined(EMU_SUPPORT_PALM_OS5) + if(palmEmulatingTungstenT3) + palmClockMultiplier = (double)percent / 100.0;//TODO, dont know ARM CPU speeds yet + else +#endif + palmClockMultiplier = (double)percent / 100.0 * (1.00 - DBVZ_CPU_PERCENT_WAITING); +} + uint32_t emulatorGetStateSize(void){ uint32_t size = 0; diff --git a/src/emulator.h b/src/emulator.h index d9a9e21..40c881c 100644 --- a/src/emulator.h +++ b/src/emulator.h @@ -47,28 +47,27 @@ static void debugLog(char* str, ...){}; //config options #define EMU_FPS 60 #define DBVZ_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 DBVZ_CPU_PERCENT_WAITING 0.30//account for wait states when reading memory, tested with SysInfo.prc #define AUDIO_SAMPLE_RATE 48000 -#define AUDIO_CLOCK_RATE 235929600//smallest amount of time a second can be split into:(2.0 * (14.0 * (255 + 1.0) + 15 + 1.0)) * 32768 == 235929600, used to convert the variable timing of SYSCLK and CLK32 to a fixed location in the current frame 0<->AUDIO_END_OF_FRAME #define AUDIO_SPEAKER_RANGE 0x6000//prevent hitting the top or bottom of the speaker when switching direction rapidly +#define SD_CARD_NCR_BYTES 1//how many 0xFF bytes come before the R1 response +#define SAVE_STATE_VERSION 0x00000001 + +//shared constants +#define AUDIO_SAMPLES_PER_FRAME (AUDIO_SAMPLE_RATE / EMU_FPS) #define SD_CARD_BLOCK_SIZE 512//all newer SDSC cards have this fixed at 512 #define SD_CARD_BLOCK_DATA_PACKET_SIZE (1 + SD_CARD_BLOCK_SIZE + 2) #define SD_CARD_RESPONSE_FIFO_SIZE (SD_CARD_BLOCK_DATA_PACKET_SIZE * 3) -#define SD_CARD_NCR_BYTES 1//how many 0xFF bytes come before the R1 response -#define SAVE_STATE_VERSION 0x00000001 -#if defined(EMU_SUPPORT_PALM_OS5) -#define SAVE_STATE_FOR_TUNGSTEN_T3 0x80000000 -#endif - //system constants +#define DBVZ_CPU_PERCENT_WAITING 0.30//account for wait states when reading memory, tested with SysInfo.prc +#define DBVZ_AUDIO_MAX_CLOCK_RATE 235929600//smallest amount of time a second can be split into:(2.0 * (14.0 * (255 + 1.0) + 15 + 1.0)) * 32768 == 235929600, used to convert the variable timing of SYSCLK and CLK32 to a fixed location in the current frame 0<->AUDIO_END_OF_FRAME +#define DBVZ_AUDIO_END_OF_FRAME (DBVZ_AUDIO_MAX_CLOCK_RATE / EMU_FPS) +#define M515_CRYSTAL_FREQUENCY 32768 #if defined(EMU_SUPPORT_PALM_OS5) #define TUNGSTEN_T3_CPU_CRYSTAL_FREQUENCY 3686400 #define TUNGSTEN_T3_RTC_CRYSTAL_FREQUENCY 32768 +#define SAVE_STATE_FOR_TUNGSTEN_T3 0x80000000 #endif -#define M515_CRYSTAL_FREQUENCY 32768 -#define AUDIO_SAMPLES_PER_FRAME (AUDIO_SAMPLE_RATE / EMU_FPS) -#define AUDIO_END_OF_FRAME (AUDIO_CLOCK_RATE / EMU_FPS) //emu errors enum{ @@ -91,12 +90,22 @@ enum{ EMU_PORT_END }; -//serial codes, behaviors of a serial connection other then the raw bytes, the data bytes are stored as uint16_t's with > 0xFF being the special codes -enum{ - EMU_SERIAL_BREAK = 0x100 -}; +//serial codes, behaviors of a serial connection other then the raw bytes, the data bytes are stored as uint16_t's with the top 8 bits being the special codes +#define EMU_SERIAL_USE_EXTERNAL_CLOCK_SOURCE 0//check baud rate against this when a serial port is reconfigured, if its equal use the clock from the other device +#define EMU_SERIAL_PARITY_ERROR 0x100 +#define EMU_SERIAL_FRAME_ERROR 0x200 +#define EMU_SERIAL_BREAK (EMU_SERIAL_PARITY_ERROR | 0x00) //types +typedef struct{ + bool enable; + bool enableParity; + bool oddParity; + uint8_t stopBits; + bool use8BitMode; + uint32_t baudRate; +}serial_port_properties_t; + typedef struct{ bool buttonUp; bool buttonDown; @@ -181,11 +190,13 @@ extern uint16_t palmFramebufferHeight;//read allowed extern int16_t* palmAudio;//read allowed, 2 channel signed 16 bit audio extern blip_t* palmAudioResampler;//dont touch extern double palmCycleCounter;//dont touch -extern double palmClockMultiplier;//read/write allowed, setting by multiplication and cacheing the result is the best way +extern double palmClockMultiplier;//dont touch +extern void (*palmIrSetPortProperties)(serial_port_properties_t* properties);//configure port I/O behavior, used for proxyed native I/R connections extern uint32_t (*palmIrDataSize)(void);//returns the current number of bytes in the hosts IR receive FIFO extern uint16_t (*palmIrDataReceive)(void);//called by the emulator to read the hosts IR receive FIFO extern void (*palmIrDataSend)(uint16_t data);//called by the emulator to send IR data extern void (*palmIrDataFlush)(void);//called by the emulator to delete all data in the hosts IR receive FIFO +extern void (*palmSerialSetPortProperties)(serial_port_properties_t* properties);//configure port I/O behavior, used for proxyed native serial connections extern uint32_t (*palmSerialDataSize)(void);//returns the current number of bytes in the hosts serial receive FIFO extern uint16_t (*palmSerialDataReceive)(void);//called by the emulator to read the hosts serial receive FIFO extern void (*palmSerialDataSend)(uint16_t data);//called by the emulator to send serial data @@ -198,6 +209,7 @@ void emulatorDeinit(void); void emulatorHardReset(void); void emulatorSoftReset(void); void emulatorSetRtc(uint16_t days, uint8_t hours, uint8_t minutes, uint8_t seconds); +void emulatorSetCpuSpeed(uint16_t percent); uint32_t emulatorGetStateSize(void); bool emulatorSaveState(uint8_t* data, uint32_t size);//true = success bool emulatorLoadState(uint8_t* data, uint32_t size);//true = success