29#if defined(__linux__) || defined(__linux) || defined(linux) || defined(__unix__) || defined(__APPLE__)
30 #define __US_LINUX_COMPILE
31#elif defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__) || defined(__MINGW64__)
32 #define __US_WINDOWS_COMPILE
35#if defined(__US_WINDOWS_COMPILE)
40 #define WINAPI __stdcall
46 #if defined(_WIN32) || defined(__CYGWIN__)
47 #define LIBUSB_CALL WINAPI
53#pragma GCC diagnostic push
54#pragma GCC diagnostic ignored "-Wunused-variable"
71 #include <stdatomic.h>
93 #define USBDBG(...) fprintf(__VA_ARGS__)
95 #define USBDBG(...) ((void)0)
97#define USBERR(...) fprintf(__VA_ARGS__)
102struct libusb_context;
103struct libusb_transfer;
120 #ifdef DEBUG_USBSID_MEMORY
147 static int run_thread;
150 #ifdef DEBUG_USBSID_MEMORY
151 static uint8_t sid_memory[0x20];
152 static uint8_t sid_memory_changed[0x20];
153 static uint16_t sid_memory_cycles[0x20];
157 static struct libusb_device_handle *devh = NULL;
158 static struct libusb_transfer *transfer_out = NULL;
159 static struct libusb_transfer *transfer_in = NULL;
160 static libusb_context *ctx = NULL;
161 static bool in_buffer_dma =
false;
162 static bool out_buffer_dma =
false;
164 static bool threaded =
false;
165 static bool withcycles =
false;
166 static int rc, read_completed, write_completed;
169 static uint8_t * __restrict__ in_buffer;
170 static uint8_t * __restrict__ out_buffer;
171 static uint8_t * __restrict__ thread_buffer;
172 static uint8_t * __restrict__ write_buffer;
173 #ifdef DEBUG_USBSID_MEMORY
174 static uint8_t * __restrict__ temp_buffer;
176 static uint8_t * __restrict__ result;
177 static int len_out_buffer;
178 static int buffer_pos = 1;
179 static int flush_buffer = 0;
186 uint8_t * __restrict__ ringbuffer;
188 static ring_buffer_t us_ringbuffer;
189 const int min_diff_size = 16;
190 const int min_ring_size = 256;
191 static int diff_size = 64;
192 static int ring_size = 8192;
248 static const enum clock_speeds clockSpeed[] = { DEFAULT, PAL, NTSC, DREAN, NTSC2 };
249 static const enum refresh_rates refreshRate[] = { HZ_DEFAULT, HZ_EU, HZ_US, HZ_US, HZ_US };
250 static const enum raster_rates rasterRate[] = { R_DEFAULT, R_EU, R_US, R_US, R_US };
251 static long cycles_per_sec = DEFAULT;
252 static long cycles_per_frame = HZ_DEFAULT;
253 static long cycles_per_raster = R_DEFAULT;
254 static int clk_retrieved = 0;
255 static long us_clkrate = 0;
256 static int numsids = 0;
257 static int fmoplsid = -1;
258 static int pcbversion = -1;
259 static int socketconfig = -1;
262 static bool us_Initialised =
false;
263 static bool us_Available =
false;
264 static bool us_PortIsOpen =
false;
265 static int instance = -1;
268 typedef std::nano ratio_t;
269 typedef std::chrono::high_resolution_clock::time_point timestamp_t;
270 typedef std::chrono::nanoseconds duration_t;
271 static double us_CPUcycleDuration = ratio_t::den / (float)cycles_per_sec;
272 static double us_InvCPUcycleDurationNanoSeconds = 1.0 / (ratio_t::den / (float)cycles_per_sec);
273 static timestamp_t m_StartTime = std::chrono::high_resolution_clock::now();
274 static timestamp_t m_LastTime = m_StartTime;
277 static std::atomic_int us_thread(0);
279 static _Atomic
int us_thread = 0;
281 static pthread_mutex_t us_mutex;
288 int LIBUSB_Setup(
bool start_threaded,
bool with_cycles);
289 int LIBUSB_Exit(
void);
290 int LIBUSB_Available(uint16_t vendor_id, uint16_t product_id);
291 void LIBUSB_StopTransfers(
void);
292 int LIBUSB_OpenDevice(
void);
293 void LIBUSB_CloseDevice(
void);
294 int LIBUSB_DetachKernelDriver(
void);
295 int LIBUSB_ConfigureDevice(
void);
296 void LIBUSB_InitOutBuffer(
void);
297 void LIBUSB_FreeOutBuffer(
void);
298 void LIBUSB_InitInBuffer(
void);
299 void LIBUSB_FreeInBuffer(
void);
300 static void LIBUSB_CALL usb_out(
struct libusb_transfer *transfer);
301 static void LIBUSB_CALL usb_in(
struct libusb_transfer *transfer);
304 unsigned char encoding[7] = { 0x40, 0x54, 0x89, 0x00, 0x00, 0x00, 0x08 };
307 void* USBSID_Thread(
void);
308 int USBSID_InitThread(
void);
309 void USBSID_StopThread(
void);
310 int USBSID_IsRunning(
void);
314 void USBSID_ResetRingBuffer(
void);
315 void USBSID_InitRingBuffer(
int buffer_size,
int differ_size);
316 void USBSID_InitRingBuffer(
void);
317 void USBSID_DeInitRingBuffer(
void);
318 bool USBSID_IsHigher(
void);
319 int USBSID_RingDiff(
void);
320 void USBSID_RingPut(uint8_t item);
321 uint8_t USBSID_RingGet(
void);
322 void USBSID_FlushBuffer(
void);
325 void USBSID_RingPopCycled(
void);
326 void USBSID_RingPop(
void);
336 int USBSID_Init(
bool start_threaded,
bool with_cycles);
337 int USBSID_Close(
void);
338 bool USBSID_isInitialised(
void){
return us_Initialised; };
339 bool USBSID_isAvailable(
void){
return us_Available; };
340 bool USBSID_isOpen(
void){
return us_PortIsOpen; };
343 void USBSID_Pause(
void);
344 void USBSID_Reset(
void);
345 void USBSID_ResetAllRegisters(
void);
346 void USBSID_Mute(
void);
347 void USBSID_UnMute(
void);
348 void USBSID_DisableSID(
void);
349 void USBSID_EnableSID(
void);
350 void USBSID_ClearBus(
void);
351 void USBSID_SetClockRate(
long clockrate_cycles,
353 long USBSID_GetClockRate(
void);
354 long USBSID_GetRefreshRate(
void);
355 long USBSID_GetRasterRate(
void);
356 uint8_t* USBSID_GetSocketConfig(uint8_t socket_config[]);
357 int USBSID_GetSocketNumSIDS(
int socket, uint8_t socket_config[]);
358 int USBSID_GetSocketChipType(
int socket, uint8_t socket_config[]);
359 int USBSID_GetSocketSIDType1(
int socket, uint8_t socket_config[]);
360 int USBSID_GetSocketSIDType2(
int socket, uint8_t socket_config[]);
361 int USBSID_GetNumSIDs(
void);
362 int USBSID_GetFMOplSID(
void);
363 int USBSID_GetPCBVersion(
void);
364 void USBSID_SetStereo(
int state);
365 void USBSID_ToggleStereo(
void);
368 void USBSID_SingleWrite(
unsigned char *buff,
int len);
369 unsigned char USBSID_SingleRead(uint8_t reg);
370 unsigned char USBSID_SingleReadConfig(
unsigned char *buff,
int len);
373 void USBSID_Write(
unsigned char *buff,
size_t len);
374 void USBSID_Write(uint8_t reg, uint8_t val);
375 void USBSID_Write(
unsigned char *buff,
size_t len, uint16_t cycles);
376 void USBSID_Write(uint8_t reg, uint8_t val, uint16_t cycles);
377 void USBSID_WriteCycled(uint8_t reg, uint8_t val, uint16_t cycles);
378 unsigned char USBSID_Read(uint8_t reg);
379 unsigned char USBSID_Read(
unsigned char *writebuff);
380 unsigned char USBSID_Read(
unsigned char *writebuff, uint16_t cycles);
383 void USBSID_WriteRing(uint8_t reg, uint8_t val);
384 void USBSID_WriteRingCycled(uint8_t reg, uint8_t val, uint16_t cycles);
387 void USBSID_EnableThread(
void);
388 void USBSID_DisableThread(
void);
391 void USBSID_SetFlush(
void);
392 void USBSID_Flush(
void);
393 void USBSID_SetBufferSize(
int size);
394 void USBSID_SetDiffSize(
int size);
395 void USBSID_RestartRingBuffer(
void);
398 void USBSID_RestartThread(
bool with_cycles);
399 static void *_USBSID_Thread(
void *context)
401 return ((USBSID_Class *)context)->USBSID_Thread();
405 uint_fast64_t USBSID_WaitForCycle(uint_fast16_t cycles);
406 uint_fast64_t USBSID_CycleFromTimestamp(timestamp_t timestamp);
410 uint8_t USBSID_Address(uint16_t addr);
417#pragma GCC diagnostic pop
418#pragma GCC pop_options