Add callbacks for reconfiguring the serial ports

This commit is contained in:
meepingsnesroms
2019-07-20 09:53:15 -07:00
parent e601bf1e15
commit 58d59a9964
4 changed files with 73 additions and 22 deletions

View File

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

View File

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

View File

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

View File

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