Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libsidplayfp for openSUSE:Factory checked in at 2026-05-24 19:35:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libsidplayfp (Old) and /work/SRC/openSUSE:Factory/.libsidplayfp.new.2084 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libsidplayfp" Sun May 24 19:35:41 2026 rev:29 rq:1354954 version:3.0.1 Changes: -------- --- /work/SRC/openSUSE:Factory/libsidplayfp/libsidplayfp.changes 2026-05-08 16:43:45.741157592 +0200 +++ /work/SRC/openSUSE:Factory/.libsidplayfp.new.2084/libsidplayfp.changes 2026-05-24 19:38:13.261589631 +0200 @@ -1,0 +2,6 @@ +Sun May 24 12:07:01 UTC 2026 - Илья Индиго <[email protected]> + +- Updated to 3.0.1 + * https://github.com/libsidplayfp/libsidplayfp/releases/tag/v3.0.1 + +------------------------------------------------------------------- Old: ---- libsidplayfp-3.0.0.tar.gz New: ---- libsidplayfp-3.0.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libsidplayfp.spec ++++++ --- /var/tmp/diff_new_pack.4iryEu/_old 2026-05-24 19:38:13.877614886 +0200 +++ /var/tmp/diff_new_pack.4iryEu/_new 2026-05-24 19:38:13.877614886 +0200 @@ -19,7 +19,7 @@ %define soname 7 %define stilview_soname 0 Name: libsidplayfp -Version: 3.0.0 +Version: 3.0.1 Release: 0 Summary: A library to play Commodore 64 music License: GPL-2.0-or-later ++++++ libsidplayfp-3.0.0.tar.gz -> libsidplayfp-3.0.1.tar.gz ++++++ ++++ 3366 lines of diff (skipped) ++++ retrying with extended exclude list diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libsidplayfp-3.0.0/NEWS.md new/libsidplayfp-3.0.1/NEWS.md --- old/libsidplayfp-3.0.0/NEWS.md 2026-05-02 10:37:29.000000000 +0200 +++ new/libsidplayfp-3.0.1/NEWS.md 2026-05-24 13:43:33.000000000 +0200 @@ -1,3 +1,10 @@ +3.0.1 2026-05-24 +* residfp: added library version to credits (#260) +* Properly check for pthreads, only error out if exsid or usbsid are required +* Updated USBSID-Pico driver + + + 3.0.0 2026-05-02 * removed deprecated stuff and cleaned up API * dropped hardsid support diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libsidplayfp-3.0.0/README.md new/libsidplayfp-3.0.1/README.md --- old/libsidplayfp-3.0.0/README.md 2026-05-02 10:37:29.000000000 +0200 +++ new/libsidplayfp-3.0.1/README.md 2026-05-24 13:43:33.000000000 +0200 @@ -1,13 +1,13 @@ libsidplayfp ============ -https://github.com/libsidplayfp/libsidplayfp - libsidplayfp is a C64 music player library which integrates the reSIDfp SID chip emulation engine into a cycle-based emulator environment, constantly aiming to improve emulation of the C64 system and the SID chips. +https://github.com/libsidplayfp/libsidplayfp + Copyright (c) 2000-2001 Simon White Copyright (c) 2007-2010 Antti Lankila Copyright (c) 2010-2026 Leandro Nini ([email protected]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libsidplayfp-3.0.0/configure.ac new/libsidplayfp-3.0.1/configure.ac --- old/libsidplayfp-3.0.0/configure.ac 2026-05-02 10:37:29.000000000 +0200 +++ new/libsidplayfp-3.0.1/configure.ac 2026-05-24 13:43:33.000000000 +0200 @@ -1,6 +1,6 @@ m4_define([lib_major], [3]) m4_define([lib_minor], [0]) -m4_define([lib_level], [0]) +m4_define([lib_level], [1]) m4_define([lib_version], [lib_major.lib_minor.lib_level]) AC_PREREQ([2.62]) @@ -96,8 +96,6 @@ ) AC_SUBST([OD], [$ac_cv_path_OD]) -AX_PTHREAD([], [AC_MSG_ERROR("pthreads not found")]) - dnl libtool-style version-info number # # https://autotools.io/libtool/version.html @@ -109,7 +107,7 @@ # Increase the age value only if the changes made to the ABI are backward compatible. LIBSIDPLAYCUR=14 -LIBSIDPLAYREV=46 +LIBSIDPLAYREV=47 LIBSIDPLAYAGE=7 LIBSIDPLAYVERSION=$LIBSIDPLAYCUR:$LIBSIDPLAYREV:$LIBSIDPLAYAGE @@ -203,6 +201,13 @@ AC_SUBST(LIBSIDPLAYVERSION) AC_SUBST(LIBSTILVIEWVERSION) +# used by exsid and usbsid +AX_PTHREAD( + [AC_DEFINE([EXSID_THREADED], 1, [Define for threaded driver])] + [AC_DEFINE([HAVE_PTHREAD_H], 1, [Define to 1 if you have pthread.h])] + [have_pthreads=yes] +) + # USBSID support AC_ARG_WITH( [usbsid], @@ -226,7 +231,7 @@ build_usbsid_builder=yes build_usbsid_driver=yes AC_MSG_RESULT([yes])], - [AC_MSG_WARN([libsub.h not found, support will not be available])] + [AC_MSG_WARN([libusb.h not found, support will not be available])] )] )] @@ -237,6 +242,11 @@ [AC_MSG_ERROR([libusb not found])] ) +AS_IF( + [test "x$with_usbsid" = "xyes" -a "x$have_pthreads" != xyes], + [AC_MSG_ERROR([pthreads not found])] +) + AC_SUBST([USBSID_CFLAGS]) AM_CONDITIONAL([USBSID_SUPPORT], [ test "x${build_usbsid_builder}" = xyes]) @@ -286,19 +296,16 @@ [AC_MSG_ERROR([Neither libexsid nor ftd2xx nor libftdi1 found])] ) +AS_IF( + [test "x$with_exsid" = "xyes" -a "x$have_pthreads" != xyes], + [AC_MSG_ERROR([pthreads not found])] +) + AC_SUBST([FTDI_CFLAGS]) AM_CONDITIONAL([EXSID_SUPPORT], [ test "x${build_exsid_builder}" = xyes]) AM_CONDITIONAL([EXSID_DRIVER], [ test "x${build_exsid_driver}" = xyes]) -# check for thread model if available -AS_IF([test "x$build_exsid_driver" = xyes], - [AX_PTHREAD( - [AC_DEFINE([EXSID_THREADED], 1, [Define for threaded driver])] - [AC_DEFINE([HAVE_PTHREAD_H], 1, [Define to 1 if you have pthread.h])] - )] -) - eval loadable_shrext=$shrext_cmds AC_DEFINE_UNQUOTED([SHLIBEXT], ["${loadable_shrext}"], [Shared library extension]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libsidplayfp-3.0.0/src/builders/residfp-builder/residfp-emu.cpp new/libsidplayfp-3.0.1/src/builders/residfp-builder/residfp-emu.cpp --- old/libsidplayfp-3.0.0/src/builders/residfp-builder/residfp-emu.cpp 2026-05-02 10:37:29.000000000 +0200 +++ new/libsidplayfp-3.0.1/src/builders/residfp-builder/residfp-emu.cpp 2026-05-24 13:43:33.000000000 +0200 @@ -31,6 +31,16 @@ # include "config.h" #endif +#define xstr(s) str(s) +#define str(s) #s + +#define _VERSION(a,b,c) a ##.## b ##.## c +#define SID_VERSION(a,b,c) _VERSION(a,b,c) +#define LIBRESIDFP_VERSION \ + SID_VERSION(LIBRESIDFP_VERSION_MAJ, \ + LIBRESIDFP_VERSION_MIN, \ + LIBRESIDFP_VERSION_LEV) + namespace libsidplayfp { @@ -41,7 +51,7 @@ return "reSIDfpEmu V" VERSION " Engine:\n" "\t(C) 1999-2002 Simon White\n" - "MOS6581/CSG8580 (SID) Emulation:\n" + "libresidfp V" xstr(LIBRESIDFP_VERSION) ":\n" "\t(C) 1999-2002 Dag Lem\n" "\t(C) 2005-2011 Antti S. Lankila\n" "\t(C) 2010-2026 Leandro Nini\n"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/ADSR.cpp new/libsidplayfp-3.0.1/src/builders/sidlite-builder/sidlite/ADSR.cpp --- old/libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/ADSR.cpp 2026-05-02 10:37:29.000000000 +0200 +++ new/libsidplayfp-3.0.1/src/builders/sidlite-builder/sidlite/ADSR.cpp 2026-05-24 13:43:33.000000000 +0200 @@ -58,9 +58,9 @@ void ADSR::clock(char cycles) { - for (int Channel=0; Channel<SID_CHANNEL_COUNT; Channel++) + for (int Channel=0, ChBase=0; Channel<SID_CHANNEL_COUNT; Channel++, ChBase+=7) { - const unsigned char *ChannelPtr = ®s[Channel*7]; + const unsigned char *ChannelPtr = ®s[ChBase]; unsigned char AD = ChannelPtr[5]; unsigned char SR = ChannelPtr[6]; unsigned char *ADSRstatePtr = &(ADSRstate[Channel]); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/WavGen.cpp new/libsidplayfp-3.0.1/src/builders/sidlite-builder/sidlite/WavGen.cpp --- old/libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/WavGen.cpp 2026-05-02 10:37:29.000000000 +0200 +++ new/libsidplayfp-3.0.1/src/builders/sidlite-builder/sidlite/WavGen.cpp 2026-05-24 13:43:33.000000000 +0200 @@ -156,9 +156,9 @@ const unsigned char FilterSwitchReso = regs[0x17]; const unsigned char VolumeBand = regs[0x18]; - for (int Channel=0; Channel<SID_CHANNEL_COUNT; Channel++) + for (int Channel=0, ChBase=0; Channel<SID_CHANNEL_COUNT; Channel++, ChBase+=7) { - unsigned char *ChannelPtr = &(regs[Channel*7]); + unsigned char *ChannelPtr = &(regs[ChBase]); auto combinedWF = [&](const cw_array_t &WFarray, unsigned short oscval) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libsidplayfp-3.0.0/src/builders/usbsid-builder/driver/src/USBSID.cpp new/libsidplayfp-3.0.1/src/builders/usbsid-builder/driver/src/USBSID.cpp --- old/libsidplayfp-3.0.0/src/builders/usbsid-builder/driver/src/USBSID.cpp 2026-05-02 10:37:31.000000000 +0200 +++ new/libsidplayfp-3.0.1/src/builders/usbsid-builder/driver/src/USBSID.cpp 2026-05-24 13:43:34.000000000 +0200 @@ -7,7 +7,7 @@ * This file is part of USBSID-Pico (https://github.com/LouDnl/USBSID-Pico-driver) * File author: LouD * - * Copyright (c) 2024-2025 LouD + * Copyright (c) 2024-2026 LouD * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,7 +38,12 @@ static inline uint8_t* us_alloc(size_t alignment, size_t size) { #if defined(__US_LINUX_COMPILE) - return (uint8_t*)aligned_alloc(alignment, size); + #ifdef HAVE_ALIGNED_ALLOC + return (uint8_t*)aligned_alloc(alignment, size); + #else + (void)alignment; + return (uint8_t*)malloc(size); + #endif #elif defined(__US_WINDOWS_COMPILE) return (uint8_t*)_aligned_malloc(size, alignment); #else @@ -114,8 +119,11 @@ if (threaded) { rc = USBSID_InitThread(); } - USBSID_GetClockRate(); /* Once on init */ us_PortIsOpen = true; + USBSID_Mute(); + USBSID_ClearBus(); + USBSID_UnMute(); + USBSID_GetClockRate(); /* Once on init */ return rc; } else { USBDBG(stdout, "[USBSID] Not found\n"); @@ -134,8 +142,9 @@ if (rc >= 0) e = LIBUSB_Exit(); if (rc != -1) USBERR(stderr, "Expected rc == -1, received: %d\n", rc); if (e != 0) USBERR(stderr, "Expected e == 0, received: %d\n", e); - if (devh != NULL) USBERR(stderr, "Expected dev == NULL, received: %p", (void*)&devh); + if (devh != NULL) USBERR(stderr, "Expected dev == NULL, received: %p\n", (void*)&devh); us_PortIsOpen = false; + us_Initialised = false; USBDBG(stdout, "[USBSID] De-init finished\n"); return 0; } @@ -271,24 +280,6 @@ return cycles_per_raster; } -/* Socket config array - * 0 = Initiator - * 1 = Verification - * 2 HiByte = socketOne enabled - * 2 LoByte = socketOne dualsid - * 3 HiByte = socketOne chipType - * 3 LoByte = socketOne cloneType - * 4 HiByte = socketOne sid1Type - * 4 LoByte = socketOne sid2Type - * 5 HiByte = socketTwo enabled - * 5 LoByte = socketTwo dualsid - * 6 HiByte = socketTwo chipType - * 6 LoByte = socketTwo cloneType - * 7 HiByte = socketTwo sid1Type - * 7 LoByte = socketTwo sid2Type - * 8 = socketTwo mirror socketOne - * 9 = Terminator - */ uint8_t* USBSID_Class::USBSID_GetSocketConfig(uint8_t socket_config[]) { if (!us_PortIsOpen) return NULL; @@ -296,16 +287,21 @@ socketconfig = 1; uint8_t configbuff[6] = {(COMMAND << 6 | CONFIG), 0x37, 0, 0, 0, 0}; USBSID_SingleWrite(configbuff, 6); - uint8_t socket_buff[10]; - USBSID_SingleReadConfig(socket_buff, 10); - if (socket_buff[0] == 0x37 - && socket_buff[1] == 0x7F - && socket_buff[9] == 0xFF) { - memcpy(socket_config, socket_buff, 10); - return socket_config; - } else { + uint8_t socket_buff[SOCKET_BUFFER_SIZE]; + int ret = USBSID_ReadConfig(socket_buff, SOCKET_BUFFER_SIZE); + if (ret != SOCKET_BUFFER_SIZE) { socketconfig = -1; return NULL; + } else { + if (socket_buff[0] == 0x37 + && socket_buff[1] == 0x7F + && socket_buff[SOCKET_BUFFER_SIZE - 1] == 0xFF) { + memcpy(socket_config, socket_buff, SOCKET_BUFFER_SIZE); + return socket_config; + } else { + socketconfig = -1; + return NULL; + } } } else { socketconfig = (socketconfig == 1 ? socketconfig : -1); @@ -337,56 +333,69 @@ }; int USBSID_Class::USBSID_GetSocketChipType(int socket, uint8_t socket_config[]) -{ /* TODO: FINISH */ - if (!us_PortIsOpen) return 0; +{ + if (!us_PortIsOpen) return 1; /* Unknown */ + switch (socket) { + case 1: + return (socket_config[3] & 0xF); + case 2: + return (socket_config[6] & 0xF); + break; + default: + return 1; /* Unknown */ + } return 0; }; /* 0 = unknown, 1 = N/A, 2 = MOS8085, 3 = MOS6581, 4 = FMopl */ int USBSID_Class::USBSID_GetSocketSIDType1(int socket, uint8_t socket_config[]) { - if (!us_PortIsOpen) return 0; + if (!us_PortIsOpen) return 1; /* N/A */ switch (socket) { case 1: - if (((socket_config[2] & 0xF0) >> 4) == 1) { + // if (((socket_config[2] & 0xF0) >> 4) == 1) { + if ((socket_config[2] & 0xF0) == 0x10) { return ((socket_config[4] & 0xF0) >> 4); } else { - return 1; + return 1; /* N/A */ } break; case 2: - if (((socket_config[5] & 0xF0) >> 4) == 1) { + // if (((socket_config[5] & 0xF0) >> 4) == 1) { + if ((socket_config[5] & 0xF0) == 0x10) { return ((socket_config[7] & 0xF0) >> 4); } else { - return 1; + return 1; /* N/A */ } break; default: - return 1; + return 1; /* N/A */ } }; /* 0 = unknown, 1 = N/A, 2 = MOS8085, 3 = MOS6581, 4 = FMopl */ int USBSID_Class::USBSID_GetSocketSIDType2(int socket, uint8_t socket_config[]) { - if (!us_PortIsOpen) return 0; + if (!us_PortIsOpen) return 1; /* N/A */ switch (socket) { case 1: - if ((((socket_config[2] & 0xF0) >> 4) == 1) && ((socket_config[2] & 0xF) == 1)) { - return ((socket_config[4] & 0xF) >> 4); + // if ((((socket_config[2] & 0xF0) >> 4) == 1) && ((socket_config[2] & 0xF) == 1)) { + if (socket_config[2] == 0x11) { + return (socket_config[4] & 0xF); } else { - return 1; + return 1; /* N/A */ } break; case 2: - if ((((socket_config[5] & 0xF0) >> 4) == 1) && ((socket_config[5] & 0xF) == 1)) { + // if ((((socket_config[5] & 0xF0) >> 4) == 1) && ((socket_config[5] & 0xF) == 1)) { + if (socket_config[5] == 0x11) { return (socket_config[7] & 0xF); } else { - return 1; + return 1; /* N/A */ } break; default: - return 1; + return 1; /* N/A */ } }; @@ -455,13 +464,14 @@ /* SYNCHRONOUS */ -void USBSID_Class::USBSID_SingleWrite(unsigned char *buff, int len) +void USBSID_Class::USBSID_SingleWrite(unsigned char *buff, size_t len) { if (!us_PortIsOpen) return; int actual_length = 0; - if (libusb_bulk_transfer(devh, EP_OUT_ADDR, buff, len, &actual_length, 0) < 0) { + if (libusb_bulk_transfer(devh, EP_OUT_ADDR, buff, len, &actual_length, LIBUSB_TIMEOUT) < 0) { USBERR(stderr, "[USBSID] Error while sending synchronous write buffer of length %d\n", actual_length); } + transfer_out_pending = false; return; } @@ -470,35 +480,57 @@ if (!us_PortIsOpen) return 0; int actual_length; unsigned char buff[3] = {(READ << 6), reg, 0}; - if (libusb_bulk_transfer(devh, EP_OUT_ADDR, buff, 3, &actual_length, 0) < 0) { + if (libusb_bulk_transfer(devh, EP_OUT_ADDR, buff, 3, &actual_length, LIBUSB_TIMEOUT) < 0) { USBERR(stderr, "[USBSID] Error while sending write command for reading\n"); } - rc = libusb_bulk_transfer(devh, EP_IN_ADDR, result, 1, &actual_length, 0); + rc = libusb_bulk_transfer(devh, EP_IN_ADDR, result, 1, &actual_length, LIBUSB_TIMEOUT); + transfer_in_pending = false; if (rc == LIBUSB_ERROR_TIMEOUT) { USBERR(stderr, "[USBSID] Timeout error while reading (%d)\n", actual_length); return 0; } else if (rc < 0) { - USBERR(stderr, "[USBSID] Error while waiting for char while reading\n"); + USBERR(stderr, "[USBSID] Error while waiting for char while reading: %d, %s: %s\n", + rc, libusb_error_name(rc), libusb_strerror(rc)); return 0; } return result[0]; } -unsigned char USBSID_Class::USBSID_SingleReadConfig(unsigned char *buff, int len) +unsigned char USBSID_Class::USBSID_SingleReadConfig(unsigned char *buff, size_t len) { if (!us_PortIsOpen) return 0; int actual_length; - rc = libusb_bulk_transfer(devh, EP_IN_ADDR, buff, len, &actual_length, 0); + rc = libusb_bulk_transfer(devh, EP_IN_ADDR, buff, len, &actual_length, LIBUSB_TIMEOUT); + transfer_in_pending = false; if (rc == LIBUSB_ERROR_TIMEOUT) { USBERR(stderr, "[USBSID] Timeout error while reading (%d)\n", actual_length); return 0; } else if (rc < 0) { - USBERR(stderr, "[USBSID] Error while waiting for char while reading\n"); + USBERR(stderr, "[USBSID] Error while waiting for char while reading: %d, %s: %s\n", + rc, libusb_error_name(rc), libusb_strerror(rc)); return 0; } return *buff; } +int USBSID_Class::USBSID_ReadConfig(unsigned char *buff, size_t len) +{ + if (!us_PortIsOpen) return 0; + int actual_length; + rc = libusb_bulk_transfer(devh, EP_IN_ADDR, buff, len, &actual_length, LIBUSB_TIMEOUT); + transfer_in_pending = false; + if (rc == LIBUSB_ERROR_TIMEOUT) { + USBERR(stderr, "[USBSID] Timeout error while reading (%d)\n", actual_length); + return 0; + } else if (rc < 0) { + USBERR(stderr, "[USBSID] Error while waiting for char while reading: %d, %s: %s\n", + rc, libusb_error_name(rc), libusb_strerror(rc)); + return 0; + } + return actual_length; +} + + /* ASYNCHRONOUS */ void USBSID_Class::USBSID_Write(unsigned char *buff, size_t len) @@ -583,14 +615,36 @@ if (!us_PortIsOpen) return 0; if (threaded == 0) { /* Reading not supported with threaded writes */ read_completed = write_completed = 0; + *result = 0; uint8_t rw_buff[2]; rw_buff[0] = (READ << 6); rw_buff[1] = reg; + + /* prepare in buffer first */ + transfer_in_pending = true; + rc = libusb_submit_transfer(transfer_in); + if (rc < 0) { + transfer_in_pending = false; + USBERR(stderr, "[USBSID] submit IN failed %d - %s: %s\n", + rc, libusb_error_name(rc), libusb_strerror(rc)); + return 0xFF; + } + /* now out buffer */ memcpy(out_buffer, rw_buff, 2); - libusb_submit_transfer(transfer_out); - libusb_handle_events_completed(ctx, NULL); - libusb_submit_transfer(transfer_in); - libusb_handle_events_completed(ctx, &read_completed); + transfer_out_pending = true; + rc = libusb_submit_transfer(transfer_out); + if (rc < 0) { + transfer_out_pending = false; + libusb_cancel_transfer(transfer_in); + USBERR(stderr, "[USBSID] submit OUT failed %d - %s: %s\n", + rc, libusb_error_name(rc), libusb_strerror(rc)); + return 0xFF; + } + while (!read_completed && transfer_in_pending) { + struct timeval tv = {0, 1000}; + libusb_handle_events_timeout_completed(ctx, &tv, NULL); + } + return *result; } else { USBERR(stderr, "[USBSID] Function '%s' cannot be used when threaded (%d) is enabled\n", __func__, threaded); @@ -603,12 +657,33 @@ if (!us_PortIsOpen) return 0; if (threaded == 0) { /* Reading not supported with threaded writes */ read_completed = write_completed = 0; + *result = 0; + + /* prepare in buffer first */ + transfer_in_pending = true; + rc = libusb_submit_transfer(transfer_in); + if (rc < 0) { + transfer_in_pending = false; + USBERR(stderr, "[USBSID] submit IN failed %d - %s: %s\n", + rc, libusb_error_name(rc), libusb_strerror(rc)); + return 0xFF; + } + /* now out buffer */ writebuff[0] = (READ << 6); memcpy(out_buffer, writebuff, 3); - libusb_submit_transfer(transfer_out); - libusb_handle_events_completed(ctx, NULL); - libusb_submit_transfer(transfer_in); - libusb_handle_events_completed(ctx, &read_completed); + transfer_out_pending = true; + rc = libusb_submit_transfer(transfer_out); + if (rc < 0) { + transfer_out_pending = false; + libusb_cancel_transfer(transfer_in); + USBERR(stderr, "[USBSID] submit OUT failed %d - %s: %s\n", + rc, libusb_error_name(rc), libusb_strerror(rc)); + return 0xFF; + } + while (!read_completed && transfer_in_pending) { + struct timeval tv = {0, 1000}; + libusb_handle_events_timeout_completed(ctx, &tv, NULL); + } return *result; } else { USBERR(stderr, "[USBSID] Function '%s' cannot be used when threaded (%d) is enabled\n", __func__, threaded); @@ -622,12 +697,33 @@ if (threaded == 0) { /* Reading not supported with threaded writes */ USBSID_WaitForCycle(cycles); read_completed = 0; + *result = 0; + + /* prepare in buffer first */ + transfer_in_pending = true; + rc = libusb_submit_transfer(transfer_in); + if (rc < 0) { + transfer_in_pending = false; + USBERR(stderr, "[USBSID] submit IN failed %d - %s: %s\n", + rc, libusb_error_name(rc), libusb_strerror(rc)); + return 0xFF; + } + /* now out buffer */ writebuff[0] = (READ << 6); memcpy(out_buffer, writebuff, 3); - libusb_submit_transfer(transfer_out); - libusb_handle_events_completed(ctx, NULL); - libusb_submit_transfer(transfer_in); - libusb_handle_events_completed(ctx, &read_completed); + transfer_out_pending = true; + rc = libusb_submit_transfer(transfer_out); + if (rc < 0) { + transfer_out_pending = false; + libusb_cancel_transfer(transfer_in); + USBERR(stderr, "[USBSID] submit OUT failed %d - %s: %s\n", + rc, libusb_error_name(rc), libusb_strerror(rc)); + return 0xFF; + } + while (!read_completed && transfer_in_pending) { + struct timeval tv = {0, 1000}; + libusb_handle_events_timeout_completed(ctx, &tv, NULL); + } return *result; } else { USBERR(stderr, "[USBSID] Function '%s' cannot be used when threaded (%d) is enabled\n", __func__, threaded); @@ -677,8 +773,8 @@ flush_buffer = 0; run_thread = buffer_pos = 1; threaded = withcycles = true; - USBSID_InitRingBuffer(ring_size, diff_size); pthread_mutex_lock(&us_mutex); + USBSID_InitRingBuffer(ring_size, diff_size); us_thread++; pthread_mutex_unlock(&us_mutex); int error; @@ -717,6 +813,8 @@ /* First check if not already running */ USBSID_StopThread(); /* Stop any active transfers */ + transfer_in_pending = false; + transfer_out_pending = false; LIBUSB_StopTransfers(); /* Free all buffers */ LIBUSB_FreeOutBuffer(); @@ -915,6 +1013,10 @@ void USBSID_Class::USBSID_RingPopCycled(void) { +#ifdef USE_VENDOR_ITF /* This can break play for tunes like Fanta in Space */ + if (transfer_out_pending) + return; +#endif thread_buffer[buffer_pos++] = USBSID_RingGet(); /* register */ thread_buffer[buffer_pos++] = USBSID_RingGet(); /* value */ thread_buffer[buffer_pos++] = USBSID_RingGet(); /* n cycles high */ @@ -927,8 +1029,13 @@ thread_buffer[0] = (uint8_t)((CYCLED_WRITE << 6) | (buffer_pos - 1)); memcpy(out_buffer, thread_buffer, buffer_pos); buffer_pos = 1; + transfer_out_pending = true; libusb_submit_transfer(transfer_out); libusb_handle_events_completed(ctx, NULL); +#ifdef USE_VENDOR_ITF /* This can break play for tunes like Fanta in Space */ + struct timeval tv = {0, 500}; // 0.5 ms + libusb_handle_events_timeout_completed(ctx, &tv, NULL); +#endif memset(thread_buffer, 0, 64); memset(out_buffer, 0, len_out_buffer); } @@ -937,6 +1044,8 @@ void USBSID_Class::USBSID_RingPop(void) { + if (transfer_out_pending) + return; write_completed = 0; /* Ex: 0xD418 */ @@ -958,42 +1067,6 @@ } -/* BUS */ - -uint8_t USBSID_Class::USBSID_Address(uint16_t addr) -{ /* Unused at the moment */ - enum { - SIDUMASK = 0xFF00, - SIDLMASK = 0xFF, - SID1ADDR = 0xD400, - SID1MASK = 0x1F, - SID2ADDR = 0xD420, - SID2MASK = 0x3F, - SID3ADDR = 0xD440, - SID3MASK = 0x5F, - SID4ADDR = 0xD460, - SID4MASK = 0x7F, - }; - /* Set address for SID no# */ - /* D500, DE00 or DF00 is the second sid in SIDTYPE1, 3 & 4 */ - /* D500, DE00 or DF00 is the third sid in all other SIDTYPE */ - static uint8_t a; - switch (addr) { - case 0xD400 ... 0xD499: - a = (uint8_t)(addr & SIDLMASK); /* $D400 -> $D479 1, 2, 3 & 4 */ - break; - case 0xD500 ... 0xD599: - case 0xDE00 ... 0xDF99: - a = ((SID3ADDR | (addr & SID2MASK)) & SIDLMASK); - break; - default: - a = (uint8_t)(addr & SIDLMASK); - break; - } - return a; -} - - /* TIMING AND CYCLES */ void USBSID_Class::USBSID_SyncTime(void) @@ -1078,6 +1151,17 @@ if (!devh) { rc = -1; USBERR(stderr, "[USBSID] Error opening USB device with VID & PID: %d %s: %s\r\n", rc, libusb_error_name(rc), libusb_strerror(rc)); + return rc; + } + /* On macOS the IOKit CDC driver will reclaim interfaces unless we enable + * auto-detach, which makes libusb detach/reattach the kernel driver + * automatically around libusb_claim_interface / libusb_release_interface. */ + rc = libusb_set_auto_detach_kernel_driver(devh, 1); + if (rc == LIBUSB_ERROR_NOT_SUPPORTED) { + /* Not supported on this platform (Windows/older libusb) — ignore */ + rc = 0; + } else if (rc < 0) { + USBERR(stderr, "[USBSID] Error setting auto detach kernel driver: %d %s: %s\r\n", rc, libusb_error_name(rc), libusb_strerror(rc)); } return rc; } @@ -1087,19 +1171,30 @@ USBDBG(stdout, "[USBSID] Close device\r\n"); if (us_InstanceID != 0) return; if (devh) { - for (int if_num = 0; if_num < 2; if_num++) { +#ifdef USE_VENDOR_ITF + /* e.g. macOS needs Vendor interface 4, others may stay with 0, 1 */ + int start_if = 4; + int end_if = 5; + /* no need to detach again... */ + rc = libusb_release_interface(devh, start_if); +#else + int start_if = 0; + int end_if = 2; + + for (int if_num = start_if; if_num < end_if; if_num++) { if (libusb_kernel_driver_active(devh, if_num)) { rc = libusb_detach_kernel_driver(devh, if_num); USBERR(stderr, "[USBSID] Error, in libusb_detach_kernel_driver: %d, %s: %s\n", rc, libusb_error_name(rc), libusb_strerror(rc)); } - libusb_release_interface(devh, if_num); + rc = libusb_release_interface(devh, if_num); } +#endif libusb_close(devh); } return; } -int USBSID_Class::LIBUSB_Available(uint16_t vendor_id, uint16_t product_id) +int USBSID_Class::LIBUSB_Available(libusb_context *ctx_, uint16_t vendor_id, uint16_t product_id) { struct libusb_device **devs; struct libusb_device *dev; @@ -1108,7 +1203,7 @@ us_Available = false; us_Found = 0; - if (libusb_get_device_list(ctx, &devs) < 0) + if (libusb_get_device_list(ctx_, &devs) < 0) return 0; while ((dev = devs[i++]) != NULL) { @@ -1136,7 +1231,16 @@ * Class defines two interfaces: the Control interface and the * Data interface. */ - for (int if_num = 0; if_num < 2; if_num++) { + int start_if, end_if; + /* macOS needs Vendor interface 4, others can stay with 0, 1 */ +#ifdef USE_VENDOR_ITF + start_if = 4; + end_if = 5; +#else + start_if = 0; + end_if = 2; +#endif + for (int if_num = start_if; if_num < end_if; if_num++) { if (libusb_kernel_driver_active(devh, if_num)) { libusb_detach_kernel_driver(devh, if_num); } @@ -1153,6 +1257,11 @@ int USBSID_Class::LIBUSB_ConfigureDevice(void) { USBDBG(stdout, "[USBSID] Configure device\r\n"); +#ifdef USE_VENDOR_ITF + /* again macOS needs this */ + rc = libusb_set_interface_alt_setting(devh, 4, 0); + rc = libusb_control_transfer(devh, 0x21, 0x22, 0x01, 4, NULL, 0, 1000); +#else /* Start configuring the device: * set line state */ rc = libusb_control_transfer(devh, 0x21, 0x22, ACM_CTRL_DTR | ACM_CTRL_RTS, 0, NULL, 0, 0); @@ -1163,12 +1272,13 @@ } /* set line encoding here */ // NOTE: NOT USED FOR CDC - rc = libusb_control_transfer(devh, 0x21, 0x20, 0, 0, encoding, sizeof(encoding), 0); + rc = libusb_control_transfer(devh, 0x21, 0x20, 0, 0, encoding, sizeof(encoding), 1000); if (rc < 0 || rc != 7) { /* should return 7 for the encoding size */ USBERR(stderr, "[USBSID] Error configuring line encoding during control transfer: %d, %s: %s\r\n", rc, libusb_error_name(rc), libusb_strerror(rc)); rc = -1; return rc; } +#endif return rc; } @@ -1186,7 +1296,7 @@ USBDBG(stdout, "[USBSID] Alloc out_buffer complete\r\n"); transfer_out = libusb_alloc_transfer(0); USBDBG(stdout, "[USBSID] Alloc transfer_out complete\r\n"); - libusb_fill_bulk_transfer(transfer_out, devh, EP_OUT_ADDR, out_buffer, len_out_buffer, usb_out, NULL, 0); + libusb_fill_bulk_transfer(transfer_out, devh, EP_OUT_ADDR, out_buffer, len_out_buffer, usb_out, NULL, LIBUSB_TIMEOUT); USBDBG(stdout, "[USBSID] libusb_fill_bulk_transfer transfer_out complete\r\n"); if (thread_buffer == NULL) { @@ -1236,7 +1346,7 @@ USBDBG(stdout, "[USBSID] Alloc in_buffer complete\r\n"); transfer_in = libusb_alloc_transfer(0); USBDBG(stdout, "[USBSID] Alloc transfer_in complete\r\n"); - libusb_fill_bulk_transfer(transfer_in, devh, EP_IN_ADDR, in_buffer, LEN_IN_BUFFER, usb_in, &read_completed, 0); + libusb_fill_bulk_transfer(transfer_in, devh, EP_IN_ADDR, in_buffer, LEN_IN_BUFFER, usb_in, this, LIBUSB_TIMEOUT); USBDBG(stdout, "[USBSID] libusb_fill_bulk_transfer transfer_in complete\r\n"); if (result == NULL) { @@ -1267,22 +1377,37 @@ void USBSID_Class::LIBUSB_StopTransfers(void) { USBDBG(stdout, "[USBSID] Stopping transfers\r\n"); - if (transfer_out != NULL) { + + if (transfer_out && transfer_out_pending) { rc = libusb_cancel_transfer(transfer_out); - libusb_free_transfer(transfer_out); - if (rc < 0 && rc != -5) { - USBERR(stderr, "[USBSID] Error, failed to cancel transfer %d - %s: %s\n", rc, libusb_error_name(rc), libusb_strerror(rc)); + if (rc < 0 && rc != LIBUSB_ERROR_NOT_FOUND) { + USBERR(stderr, "[USBSID] Error cancel OUT %d - %s: %s\n", + rc, libusb_error_name(rc), libusb_strerror(rc)); } } - if (transfer_in != NULL) { + if (transfer_in && transfer_in_pending) { rc = libusb_cancel_transfer(transfer_in); - libusb_free_transfer(transfer_in); - if (rc < 0 && rc != -5) { - USBERR(stderr, "[USBSID] Error, failed to cancel transfer %d - %s: %s\n", rc, libusb_error_name(rc), libusb_strerror(rc)); + if (rc < 0 && rc != LIBUSB_ERROR_NOT_FOUND) { + USBERR(stderr, "[USBSID] Error cancel IN %d - %s: %s\n", + rc, libusb_error_name(rc), libusb_strerror(rc)); } } - return; + + while (transfer_out_pending || transfer_in_pending) { + struct timeval tv = {0, 1000}; + libusb_handle_events_timeout_completed(ctx, &tv, NULL); + } + + if (transfer_out) { + libusb_free_transfer(transfer_out); + transfer_out = NULL; + } + + if (transfer_in) { + libusb_free_transfer(transfer_in); + transfer_in = NULL; + } } int USBSID_Class::LIBUSB_Setup(bool start_threaded, bool with_cycles) @@ -1307,7 +1432,7 @@ libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, 0); /* Check for an available USBSID-Pico */ - if (LIBUSB_Available(VENDOR_ID, PRODUCT_ID) <= 0) { + if (LIBUSB_Available(ctx, VENDOR_ID, PRODUCT_ID) <= 0) { USBDBG(stderr, "[USBSID] USBSID-Pico not connected\n"); goto out; } @@ -1315,12 +1440,15 @@ if (LIBUSB_OpenDevice() < 0) { goto out; } + if (LIBUSB_DetachKernelDriver() < 0) { goto out; } + if (LIBUSB_ConfigureDevice() < 0) { goto out; } + #ifdef US_UNMUTE_ON_ENTRY USBSID_UnMute(); #endif @@ -1359,6 +1487,8 @@ #ifdef US_RESET_ON_EXIT USBSID_Reset(); #endif + transfer_in_pending = false; + transfer_out_pending = false; LIBUSB_StopTransfers(); LIBUSB_FreeInBuffer(); LIBUSB_FreeOutBuffer(); @@ -1367,7 +1497,7 @@ if (ctx) { libusb_exit(ctx); } - + ctx = NULL; rc = -1; devh = NULL; USBDBG(stdout, "[USBSID] Closed USB device\r\n"); @@ -1382,34 +1512,48 @@ USBERR(stderr, "[USBSID] Warning: transfer out interrupted with status %d, %s: %s\r", rc, libusb_error_name(rc), libusb_strerror(rc)); } libusb_free_transfer(transfer); + transfer_out = NULL; return; } if (transfer->actual_length != len_out_buffer) { USBERR(stderr, "[USBSID] Sent data length %d is different from the defined buffer length: %d or actual length %d\r", transfer->length, len_out_buffer, transfer->actual_length); } - - // BUG: Resubmit is shit for normal tunes but good for cycle exact digitunes, sigh... + // WARNING: Resubmit is shit for normal tunes but good for cycle exact digitunes, sigh... // if (threaded) libusb_submit_transfer(transfer_out); /* Resubmit queue when finished */ - return; + //libusb_free_transfer(transfer); + //transfer_out = NULL; + transfer_out_pending = false; } void LIBUSB_CALL USBSID_Class::usb_in(struct libusb_transfer *transfer) { - read_completed = (*(int *)transfer->user_data); + if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { + rc = transfer->status; - if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { - rc = transfer_in->status; - if (rc != LIBUSB_TRANSFER_CANCELLED) { - USBERR(stderr, "[USBSID] Warning: transfer in interrupted with status '%s'\r", libusb_error_name(rc)); - } - libusb_free_transfer(transfer); - return; - } - - memcpy(result, in_buffer, 1); - read_completed = 1; - return; + if (rc != LIBUSB_TRANSFER_CANCELLED) { + USBERR(stderr, + "[USBSID] Warning: transfer in interrupted with status '%s'\r", + libusb_error_name(rc)); + } + + libusb_free_transfer(transfer); + transfer_in = NULL; + return; + } + + if (transfer->actual_length > 0) { + memcpy(result, in_buffer, 1); + } + + if (transfer->user_data) { + *(int *)transfer->user_data = 1; + } + + read_completed = 1; + transfer_in_pending = false; + //libusb_free_transfer(transfer); + //transfer_in = NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libsidplayfp-3.0.0/src/builders/usbsid-builder/driver/src/USBSID.h new/libsidplayfp-3.0.1/src/builders/usbsid-builder/driver/src/USBSID.h --- old/libsidplayfp-3.0.0/src/builders/usbsid-builder/driver/src/USBSID.h 2026-05-02 10:37:31.000000000 +0200 +++ new/libsidplayfp-3.0.1/src/builders/usbsid-builder/driver/src/USBSID.h 2026-05-24 13:43:34.000000000 +0200 @@ -7,7 +7,7 @@ * This file is part of USBSID-Pico (https://github.com/LouDnl/USBSID-Pico-driver) * File author: LouD * - * Copyright (c) 2024-2025 LouD + * Copyright (c) 2024-2026 LouD * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +26,14 @@ #ifndef _USBSID_H_ #define _USBSID_H_ +#ifdef __APPLE__ +#undef HAVE_ALIGNED_ALLOC +#define USE_VENDOR_ITF +#define LIBUSB_TIMEOUT 1000 +#else +#define LIBUSB_TIMEOUT 0 +#endif + #if defined(__linux__) || defined(__linux) || defined(linux) || defined(__unix__) || defined(__APPLE__) #define __US_LINUX_COMPILE #elif defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__) || defined(__MINGW64__) @@ -135,8 +143,13 @@ PRODUCT_ID = 0x4011, ACM_CTRL_DTR = 0x01, ACM_CTRL_RTS = 0x02, +#ifdef USE_VENDOR_ITF + EP_OUT_ADDR = 0x04, + EP_IN_ADDR = 0x84, +#else EP_OUT_ADDR = 0x02, EP_IN_ADDR = 0x82, +#endif LEN_IN_BUFFER = 1, LEN_OUT_BUFFER = 64, #ifdef DEBUG_USBSID_MEMORY @@ -165,6 +178,30 @@ BOOTLOADER = 20, /* 0b10100 ~ 0x14 */ }; + /* Socket config array + * 0 Initiator = 0x37 + * 1 Verification = 0x7f + * 2 HiByte = socketOne enabled + * 2 LoByte = socketOne dualsid + * 3 LoByte = socketOne chipType + * 4 HiByte = socketOne sid1Type + * 4 LoByte = socketOne sid2Type + * 5 HiByte = socketTwo enabled + * 5 LoByte = socketTwo dualsid + * 6 LoByte = socketTwo chipType + * 7 HiByte = socketTwo sid1Type + * 7 LoByte = socketTwo sid2Type + * 8 HiByte = socketOne SID1 id + * 8 LoByte = socketOne SID2 id + * 9 HiByte = socketOne SID1 id + * 9 LoByte = socketOne SID2 id + * 10 LoByte 0b001 = socketTwo mirrors socketOne + * 10 LoByte 0b010 = sockets are flipped One is Two and vice versa + * 10 LoByte 0b100 = SID addresses are mixed (quad sid only) + * 11 Terminator = 0xff + */ + #define SOCKET_BUFFER_SIZE 12 + /* Thread related */ static int run_thread; @@ -179,6 +216,9 @@ static struct libusb_device_handle *devh = NULL; static struct libusb_transfer *transfer_out = NULL; /* OUT-going transfers (OUT from host PC to USB-device) */ static struct libusb_transfer *transfer_in = NULL; /* IN-coming transfers (IN to host PC from USB-device) */ + static bool transfer_out_pending = false; /* for better transfer sync */ + static bool transfer_in_pending = false; + static libusb_context *ctx = NULL; static bool in_buffer_dma = false; static bool out_buffer_dma = false; @@ -317,7 +357,7 @@ /* LIBUSB */ int LIBUSB_Setup(bool start_threaded, bool with_cycles); int LIBUSB_Exit(void); - int LIBUSB_Available(uint16_t vendor_id, uint16_t product_id); + int LIBUSB_Available(libusb_context *ctx_, uint16_t vendor_id, uint16_t product_id); void LIBUSB_StopTransfers(void); int LIBUSB_OpenDevice(void); void LIBUSB_CloseDevice(void); @@ -361,83 +401,80 @@ ~USBSID_Class(); /* Deconstructor */ /* USBSID */ - int USBSID_Init(bool start_threaded, bool with_cycles); - int USBSID_Close(void); - int USBSID_GetInstanceID(void){ return us_InstanceID; }; - bool USBSID_isInitialised(void){ return us_Initialised; }; - bool USBSID_isAvailable(void){ return us_Available; }; - bool USBSID_isOpen(void){ return us_PortIsOpen; }; + int USBSID_Init(bool start_threaded, bool with_cycles); /* Well it inits? */ + int USBSID_Close(void); /* And this does not */ + int USBSID_GetInstanceID(void){ return us_InstanceID; }; /* Does it count? */ + bool USBSID_isInitialised(void){ return us_Initialised; }; /* Probability 50% */ + bool USBSID_isAvailable(void){ return us_Available; }; /* Only if you're nice */ + bool USBSID_isOpen(void){ return us_PortIsOpen; }; /* Adults only */ /* USBSID & SID control */ - void USBSID_Pause(void); /* Pause playing by releasing chipselect pins */ - void USBSID_Reset(void); /* Reset all SID chips */ - void USBSID_ResetAllRegisters(void); /* Reset register for all SID chips */ - void USBSID_Mute(void); /* Mute all SID chips */ - void USBSID_UnMute(void); /* UnMute all SID chips */ - void USBSID_DisableSID(void); /* Release reset pin and unmute SID */ - void USBSID_EnableSID(void); /* Assert reset pin and release chipselect pins */ - void USBSID_ClearBus(void); /* Clear the SID bus from any data */ - void USBSID_SetClockRate(long clockrate_cycles, /* Set CPU clockrate in Hertz */ - bool suspend_sids); /* Assert SID RES signal while changing clockrate (Advised!)*/ - long USBSID_GetClockRate(void); /* Get CPU clockrate in Hertz */ - long USBSID_GetRefreshRate(void); /* Get cycles per refresh rate */ - long USBSID_GetRasterRate(void); /* Get cycles per raster rate */ - uint8_t* USBSID_GetSocketConfig(uint8_t socket_config[]); /* Get socket config for parsing */ - int USBSID_GetSocketNumSIDS(int socket, uint8_t socket_config[]); /* Get the socket number of sids configured */ - int USBSID_GetSocketChipType(int socket, uint8_t socket_config[]); /* Get the socket chip type configured */ - int USBSID_GetSocketSIDType1(int socket, uint8_t socket_config[]); /* Get the socket SID 1 type configured */ - int USBSID_GetSocketSIDType2(int socket, uint8_t socket_config[]); /* Get the socket SID 2 type configured (only works for clone chip types ofcourse) */ - int USBSID_GetNumSIDs(void); /* Get the total number of sids configured */ - int USBSID_GetFMOplSID(void); /* Get the sid number (if configured) to address FMOpl */ - int USBSID_GetPCBVersion(void); /* Get the PCB version */ - void USBSID_SetStereo(int state); /* Set device to mono or stereo ~ v1.3 PCB only */ - void USBSID_ToggleStereo(void); /* Toggle between mono and stereo ~ v1.3 PCB only */ + void USBSID_Pause(void); /* Pause playing by releasing chipselect pins */ + void USBSID_Reset(void); /* Reset all SID chips */ + void USBSID_ResetAllRegisters(void); /* Reset register for all SID chips */ + void USBSID_Mute(void); /* Mute all SID chips */ + void USBSID_UnMute(void); /* UnMute all SID chips */ + void USBSID_DisableSID(void); /* Release reset pin and unmute SID */ + void USBSID_EnableSID(void); /* Assert reset pin and release chipselect pins */ + void USBSID_ClearBus(void); /* Clear the SID bus from any data */ + void USBSID_SetClockRate(long clockrate_cycles, /* Set CPU clockrate in Hertz */ + bool suspend_sids); /* Assert SID RES signal while changing clockrate (Advised!)*/ + long USBSID_GetClockRate(void); /* Get CPU clockrate in Hertz */ + long USBSID_GetRefreshRate(void); /* Get cycles per refresh rate */ + long USBSID_GetRasterRate(void); /* Get cycles per raster rate */ + uint8_t* USBSID_GetSocketConfig(uint8_t socket_config[]); /* Get socket config for parsing */ + int USBSID_GetSocketNumSIDS(int socket, uint8_t socket_config[]); /* Get the socket number of sids configured */ + int USBSID_GetSocketChipType(int socket, uint8_t socket_config[]); /* Get the socket chip type configured */ + int USBSID_GetSocketSIDType1(int socket, uint8_t socket_config[]); /* Get the socket SID 1 type configured */ + int USBSID_GetSocketSIDType2(int socket, uint8_t socket_config[]); /* Get the socket SID 2 type configured (only works for clone chip types ofcourse) */ + int USBSID_GetNumSIDs(void); /* Get the total number of sids configured */ + int USBSID_GetFMOplSID(void); /* Get the sid number (if configured) to address FMOpl */ + int USBSID_GetPCBVersion(void); /* Get the PCB version */ + void USBSID_SetStereo(int state); /* Set device to mono or stereo ~ v1.3 PCB only */ + void USBSID_ToggleStereo(void); /* Toggle between mono and stereo ~ v1.3 PCB only */ /* Synchronous direct */ - void USBSID_SingleWrite(unsigned char *buff, int len); /* Single write buffer of size_t ~ example: config writing */ + void USBSID_SingleWrite(unsigned char *buff, size_t len); /* Single write buffer of size_t ~ example: config writing */ unsigned char USBSID_SingleRead(uint8_t reg); /* Single read register, return result */ - unsigned char USBSID_SingleReadConfig(unsigned char *buff, int len); /* Single to buffer of specified length ~ example: config reading */ + unsigned char USBSID_SingleReadConfig(unsigned char *buff, size_t len); /* Single to buffer of specified length ~ example: config reading */ + int USBSID_ReadConfig(unsigned char *buff, size_t len); /* Single to buffer of specified length ~ returns size of data */ /* Asynchronous direct */ - void USBSID_Write(unsigned char *buff, size_t len); /* Write buffer of size_t len */ - void USBSID_Write(uint8_t reg, uint8_t val); /* Write register and value */ - void USBSID_Write(unsigned char *buff, size_t len, uint16_t cycles); /* Wait n cycles, write buffer of size_t len */ - void USBSID_Write(uint8_t reg, uint8_t val, uint16_t cycles); /* Wait n cycles, write register and value */ - void USBSID_WriteCycled(uint8_t reg, uint8_t val, uint16_t cycles); /* Write register and value, USBSID uses cycles for delay */ - unsigned char USBSID_Read(uint8_t reg); /* Write register, return result */ - unsigned char USBSID_Read(unsigned char *writebuff); /* Write buffer, return result */ - unsigned char USBSID_Read(unsigned char *writebuff, uint16_t cycles); /* Wait for n cycles and write buffer, return result */ + void USBSID_Write(unsigned char *buff, size_t len); /* Write buffer of size_t len */ + void USBSID_Write(uint8_t reg, uint8_t val); /* Write register and value */ + void USBSID_Write(unsigned char *buff, size_t len, uint16_t cycles); /* Wait n cycles, write buffer of size_t len */ + void USBSID_Write(uint8_t reg, uint8_t val, uint16_t cycles); /* Wait n cycles, write register and value */ + void USBSID_WriteCycled(uint8_t reg, uint8_t val, uint16_t cycles); /* Write register and value, USBSID uses cycles for delay */ + unsigned char USBSID_Read(uint8_t reg); /* Write register, return result */ + unsigned char USBSID_Read(unsigned char *writebuff); /* Write buffer, return result */ + unsigned char USBSID_Read(unsigned char *writebuff, uint16_t cycles); /* Wait for n cycles and write buffer, return result */ /* Asynchronous thread */ void USBSID_WriteRing(uint8_t reg, uint8_t val); /* Write register and value to ringbuffer, USBSID adds 10 delay cycles to each write */ void USBSID_WriteRingCycled(uint8_t reg, uint8_t val, uint16_t cycles); /* Write register, value, and cycles to ringbuffer */ /* Threading */ - void USBSID_EnableThread(void); /* Enable the thread on the fly */ - void USBSID_DisableThread(void); /* Disable the running thread and switch to non threaded and cycled on the fly */ + void USBSID_EnableThread(void); /* Enable the thread on the fly */ + void USBSID_DisableThread(void); /* Disable the running thread and switch to non threaded and cycled on the fly */ /* Ringbuffer */ - void USBSID_SetFlush(void); /* Set flush buffer flag to 1 */ - void USBSID_Flush(void); /* Set flush buffer flag to 1 and flushes the buffer */ - void USBSID_SetBufferSize(int size); /* Set the buffer size for storing writes */ - void USBSID_SetDiffSize(int size); /* Set the minimum size difference between head & tail */ - void USBSID_RestartRingBuffer(void); /* Restart the ringbuffer*/ + void USBSID_SetFlush(void); /* Set flush buffer flag to 1 */ + void USBSID_Flush(void); /* Set flush buffer flag to 1 and flushes the buffer */ + void USBSID_SetBufferSize(int size); /* Set the buffer size for storing writes */ + void USBSID_SetDiffSize(int size); /* Set the minimum size difference between head & tail */ + void USBSID_RestartRingBuffer(void); /* Restart the ringbuffer */ /* Thread utils */ - void USBSID_RestartThread(bool with_cycles); - static void *_USBSID_Thread(void *context) + void USBSID_RestartThread(bool with_cycles); /* Restart the thread that handles the ringbuffer */ + static void *_USBSID_Thread(void *context) /* Internal wrapper to start the thread */ { /* Required for supplying private function to pthread_create */ return ((USBSID_Class *)context)->USBSID_Thread(); } /* Timing and cycles */ - uint_fast64_t USBSID_WaitForCycle(uint_fast16_t cycles); /* Sleep for n cycles */ - uint_fast64_t USBSID_WaitForCycle_(uint_fast16_t cycles); /* Sleep for n cycles ~ deprecated */ - void USBSID_SyncTime(void); /* Sync time for cycle delay function */ - - /* Utils */ - /* TODO: Deprecate this function, emulator/player should handle this */ - uint8_t USBSID_Address(uint16_t addr); /* Calculates correct SID address to write to if player does not */ + uint_fast64_t USBSID_WaitForCycle(uint_fast16_t cycles); /* Sleep for n cycles */ + uint_fast64_t USBSID_WaitForCycle_(uint_fast16_t cycles); /* Sleep for n cycles ~ deprecated */ + void USBSID_SyncTime(void); /* Sync time for cycle delay function */ }; } /* USBSIDDriver */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libsidplayfp-3.0.0/src/config.h.in new/libsidplayfp-3.0.1/src/config.h.in --- old/libsidplayfp-3.0.0/src/config.h.in 2026-05-02 10:37:35.000000000 +0200 +++ new/libsidplayfp-3.0.1/src/config.h.in 2026-05-24 13:43:38.000000000 +0200 @@ -57,9 +57,6 @@ /* Define to 1 if you have the <libusb-1.0/libusb.h> header file. */ #undef HAVE_LIBUSB_1_0_LIBUSB_H -/* Define if you have POSIX threads libraries and header files. */ -#undef HAVE_PTHREAD - /* Define to 1 if you have pthread.h */ #undef HAVE_PTHREAD_H diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/libsidplayfp-3.0.0/test/demo.cpp new/libsidplayfp-3.0.1/test/demo.cpp --- old/libsidplayfp-3.0.0/test/demo.cpp 2026-05-02 10:37:29.000000000 +0200 +++ new/libsidplayfp-3.0.1/test/demo.cpp 2026-05-24 13:43:33.000000000 +0200 @@ -109,18 +109,11 @@ // Set up a SID builder std::unique_ptr<SIDLiteBuilder> rs(new SIDLiteBuilder("Demo")); -/* - // Check if builder is ok - if (!rs->getStatus()) - { - std::cerr << rs->error() << std::endl; - return -1; - } -*/ + // Load tune from file std::unique_ptr<SidTune> tune(new SidTune(argv[1])); - // CHeck if the tune is valid + // Check if the tune is valid if (!tune->getStatus()) { std::cerr << tune->statusString() << std::endl; @@ -148,7 +141,7 @@ return -1; } - // Setup audio device + // Setup audio device (platform dependent) int handle=::open("/dev/dsp", O_WRONLY, 0); int format=AFMT_S16_LE; ioctl(handle, SNDCTL_DSP_SETFMT, &format); @@ -159,23 +152,33 @@ int bufferSize; ioctl(handle, SNDCTL_DSP_GETBLKSIZE, &bufferSize); - //uint_least32_t bufferSamples = static_cast<uint_least32_t>(bufferSize) / sizeof(short); - + // Number of cycles to run the emulation at each step + // 5000 cycles at ~1MHz = ~5ms constexpr int CYCLES = 5000; + // Initialize the mixer for stereo output m_engine.initMixer(true); + + // Get an estimate for the buffer size required int bufSize = m_engine.getBufSize(CYCLES); + + // Prepare the buffer std::vector<short> buffer(bufSize); + // Play for ~5 seconds for (int i=0; i<1000; i++) { + // Run the emulation int res = m_engine.play(CYCLES); if (res < 0) { std::cerr << m_engine.error() << std::endl; break; } + + // Mix the audio into the output buffer unsigned int s = m_engine.mix(buffer.data(), res); + ::write(handle, buffer.data(), s*sizeof(short)); }
