30#undef HAVE_ALIGNED_ALLOC
32#define LIBUSB_TIMEOUT 1000
34#define LIBUSB_TIMEOUT 0
37#if defined(__linux__) || defined(__linux) || defined(linux) || defined(__unix__) || defined(__APPLE__)
38 #define __US_LINUX_COMPILE
39#elif defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__) || defined(__MINGW64__)
40 #define __US_WINDOWS_COMPILE
48#if defined(__US_WINDOWS_COMPILE)
50 #if defined(__aarch64__) || defined(_M_ARM64) || defined(__arm__) || defined(_M_ARM) || defined(_ARM_)
59 #define WINAPI __stdcall
62 #define LIBUSB_CALL WINAPI
72#pragma GCC diagnostic push
73#pragma GCC diagnostic ignored "-Wunused-variable"
90 #include <stdatomic.h>
98#if defined(__clang__) && defined(__MINGW32__)
99 #if defined(__x86_64__) || defined(__aarch64__)
123 #define USBDBG(...) fprintf(__VA_ARGS__)
125 #define USBDBG(...) ((void)0)
127#define USBERR(...) fprintf(__VA_ARGS__)
132struct libusb_context;
133struct libusb_transfer;
155 #ifdef DEBUG_USBSID_MEMORY
203 #define SOCKET_BUFFER_SIZE 12
206 static int run_thread;
209 #ifdef DEBUG_USBSID_MEMORY
210 static uint8_t sid_memory[0x20];
211 static uint8_t sid_memory_changed[0x20];
212 static uint16_t sid_memory_cycles[0x20];
216 static struct libusb_device_handle *devh = NULL;
217 static struct libusb_transfer *transfer_out = NULL;
218 static struct libusb_transfer *transfer_in = NULL;
219 static bool transfer_out_pending =
false;
220 static bool transfer_in_pending =
false;
222 static libusb_context *ctx = NULL;
223 static bool in_buffer_dma =
false;
224 static bool out_buffer_dma =
false;
226 static bool threaded =
false;
227 static bool withcycles =
false;
228 static int rc, read_completed, write_completed;
231 static uint8_t * __restrict__ in_buffer;
232 static uint8_t * __restrict__ out_buffer;
233 static uint8_t * __restrict__ thread_buffer;
234 static uint8_t * __restrict__ write_buffer;
235 #ifdef DEBUG_USBSID_MEMORY
236 static uint8_t * __restrict__ temp_buffer;
238 static uint8_t * __restrict__ result;
239 static int len_out_buffer;
240 static int buffer_pos = 1;
241 static int flush_buffer = 0;
248 uint8_t * __restrict__ ringbuffer;
250 static ring_buffer_t us_ringbuffer;
251 const int min_diff_size = 16;
252 const int min_ring_size = 256;
253 const int default_diff_size = 64;
254 const int default_ring_size = 8192;
310 static const enum clock_speeds clockSpeed[] = { DEFAULT, PAL, NTSC, DREAN, NTSC2 };
311 static const enum refresh_rates refreshRate[] = { HZ_DEFAULT, HZ_EU, HZ_US, HZ_US, HZ_US };
312 static const enum raster_rates rasterRate[] = { R_DEFAULT, R_EU, R_US, R_US, R_US };
313 static long cycles_per_sec = DEFAULT;
314 static long cycles_per_frame = HZ_DEFAULT;
315 static long cycles_per_raster = R_DEFAULT;
316 static int clk_retrieved = 0;
317 static long us_clkrate = 0;
318 static int numsids = 0;
319 static int fmoplsid = -1;
320 static int pcbversion = -1;
321 static int socketconfig = -1;
324 static int us_Found = 0;
325 static int instance = -1;
328 typedef std::nano ratio_t;
329 typedef std::chrono::steady_clock::time_point timestamp_t;
330 typedef std::chrono::nanoseconds duration_t;
333 static std::atomic_int us_thread(0);
335 static _Atomic
int us_thread = 0;
337 static pthread_mutex_t us_mutex;
342 static bool us_Initialised;
343 static bool us_Available;
344 static bool us_PortIsOpen;
348 static double us_CPUcycleDuration;
349 static double us_InvCPUcycleDurationNanoSeconds;
350 static timestamp_t m_StartTime;
351 static timestamp_t m_LastTime;
354 static int diff_size;
355 static int ring_size;
358 int LIBUSB_Setup(
bool start_threaded,
bool with_cycles);
359 int LIBUSB_Exit(
void);
360 int LIBUSB_Available(libusb_context *ctx_, uint16_t vendor_id, uint16_t product_id);
361 void LIBUSB_StopTransfers(
void);
362 int LIBUSB_OpenDevice(
void);
363 void LIBUSB_CloseDevice(
void);
364 int LIBUSB_DetachKernelDriver(
void);
365 int LIBUSB_ConfigureDevice(
void);
366 void LIBUSB_InitOutBuffer(
void);
367 void LIBUSB_FreeOutBuffer(
void);
368 void LIBUSB_InitInBuffer(
void);
369 void LIBUSB_FreeInBuffer(
void);
370 static void LIBUSB_CALL usb_out(
struct libusb_transfer *transfer);
371 static void LIBUSB_CALL usb_in(
struct libusb_transfer *transfer);
374 unsigned char encoding[7] = { 0x40, 0x54, 0x89, 0x00, 0x00, 0x00, 0x08 };
377 void* USBSID_Thread(
void);
378 int USBSID_InitThread(
void);
379 void USBSID_StopThread(
void);
380 int USBSID_IsRunning(
void);
384 void USBSID_ResetRingBuffer(
void);
385 void USBSID_InitRingBuffer(
int buffer_size,
int differ_size);
386 void USBSID_InitRingBuffer(
void);
387 void USBSID_DeInitRingBuffer(
void);
388 bool USBSID_IsHigher(
void);
389 int USBSID_RingDiff(
void);
390 void USBSID_RingPut(uint8_t item);
391 uint8_t USBSID_RingGet(
void);
392 void USBSID_FlushBuffer(
void);
395 void USBSID_RingPopCycled(
void);
396 void USBSID_RingPop(
void);
404 int USBSID_Init(
bool start_threaded,
bool with_cycles);
405 int USBSID_Close(
void);
406 int USBSID_GetInstanceID(
void){
return us_InstanceID; };
407 bool USBSID_isInitialised(
void){
return us_Initialised; };
408 bool USBSID_isAvailable(
void){
return us_Available; };
409 bool USBSID_isOpen(
void){
return us_PortIsOpen; };
412 void USBSID_Pause(
void);
413 void USBSID_Reset(
void);
414 void USBSID_ResetAllRegisters(
void);
415 void USBSID_Mute(
void);
416 void USBSID_UnMute(
void);
417 void USBSID_DisableSID(
void);
418 void USBSID_EnableSID(
void);
419 void USBSID_ClearBus(
void);
420 void USBSID_SetClockRate(
long clockrate_cycles,
422 long USBSID_GetClockRate(
void);
423 long USBSID_GetRefreshRate(
void);
424 long USBSID_GetRasterRate(
void);
425 uint8_t* USBSID_GetSocketConfig(uint8_t socket_config[]);
426 int USBSID_GetSocketNumSIDS(
int socket, uint8_t socket_config[]);
427 int USBSID_GetSocketChipType(
int socket, uint8_t socket_config[]);
428 int USBSID_GetSocketSIDType1(
int socket, uint8_t socket_config[]);
429 int USBSID_GetSocketSIDType2(
int socket, uint8_t socket_config[]);
430 int USBSID_GetNumSIDs(
void);
431 int USBSID_GetFMOplSID(
void);
432 int USBSID_GetPCBVersion(
void);
433 void USBSID_SetStereo(
int state);
434 void USBSID_ToggleStereo(
void);
437 void USBSID_SingleWrite(
unsigned char *buff,
size_t len);
438 unsigned char USBSID_SingleRead(uint8_t reg);
439 unsigned char USBSID_SingleReadConfig(
unsigned char *buff,
size_t len);
440 int USBSID_ReadConfig(
unsigned char *buff,
size_t len);
443 void USBSID_Write(
unsigned char *buff,
size_t len);
444 void USBSID_Write(uint8_t reg, uint8_t val);
445 void USBSID_Write(
unsigned char *buff,
size_t len, uint16_t cycles);
446 void USBSID_Write(uint8_t reg, uint8_t val, uint16_t cycles);
447 void USBSID_WriteCycled(uint8_t reg, uint8_t val, uint16_t cycles);
448 unsigned char USBSID_Read(uint8_t reg);
449 unsigned char USBSID_Read(
unsigned char *writebuff);
450 unsigned char USBSID_Read(
unsigned char *writebuff, uint16_t cycles);
453 void USBSID_WriteRing(uint8_t reg, uint8_t val);
454 void USBSID_WriteRingCycled(uint8_t reg, uint8_t val, uint16_t cycles);
457 void USBSID_EnableThread(
void);
458 void USBSID_DisableThread(
void);
461 void USBSID_SetFlush(
void);
462 void USBSID_Flush(
void);
463 void USBSID_SetBufferSize(
int size);
464 void USBSID_SetDiffSize(
int size);
465 void USBSID_RestartRingBuffer(
void);
468 void USBSID_RestartThread(
bool with_cycles);
469 static void *_USBSID_Thread(
void *context)
471 return ((USBSID_Class *)context)->USBSID_Thread();
475 uint_fast64_t USBSID_WaitForCycle(uint_fast16_t cycles);
476 uint_fast64_t USBSID_WaitForCycle_(uint_fast16_t cycles);
477 void USBSID_SyncTime(
void);
484#pragma GCC diagnostic pop
485#pragma GCC pop_options